Agent:
  name: Law-aid_Civil_Suit_Plaintiff_Claim_Agent
  description: 민사소송 원고 대리 에이전트 - 사건개요 추출부터 소장 작성까지
  version: '1.0'
  
  Stages:
    - name: stage1_사건개요파악 
      description: 사건개요 파악 및 개요도 추출
      llm_provider: openai
      llm_model: gpt-4o-2024-08-06
      tools:
        mcpServers:
          localdocs:
            type: streamable-http
            url: "http://mcp-localdocs:8012/mcp"
            description: Get the content of local documents
          code-executor:
            type: streamable-http
            url: https://code-executor.mcp.eroomai.com/mcp
            description: Run scripts of programming languages
            headers:
              Authorization: Bearer rR8OXqWrVZA1gFEo8oWfBkw2XgpWoGrrspw5ObsxTCM=  

      tasks:
        - task_name: Task_A
          llm_provider: google
          llm_model: 'gemini-3.1-flash-lite-preview'
          llm_reasoning: high
          llm_verbosity: medium
          cache_control:
            mode: auto
            ttl: 10m          
          use_tools:
          - localdocs
          prompts:
          - role: user
            content: |-
              <ABSOLUTE_SYSTEM_RULES>
              - You MUST execute every single instruction provided below without any omission.
              - DO NOT arbitrarily reduce, summarize, or skip any steps, reasoning processes, or outputs.
              - DO NOT use placeholders like "..." or "rest of the code/text". Provide the exhaustive and complete output.
              - Adhere strictly to these rules before processing the prompt.
              </ABSOLUTE_SYSTEM_RULES>

              <COMMON_CACHE_PREFIX_STAGE_1>
                <STAGE_CONTEXT>
                당신은 대한민국 민사소송 원고대리 사건을 구조화하는 Stage 1 전용 정밀 LLM이다.
                이 프롬프트는 LLM의 안정적 추론, 구조 보존, 식별자 보존, 후속 단계 조인 안정성을 최우선으로 설계되었다.                
                </STAGE_CONTEXT>

                <CACHE_HIT_POLICY>
                - 이 블록은 Stage 1의 Task_A, Task_B1, Task_B2, Task_B3, Task_C, Task_D1, Task_D2에서 byte-level로 최대한 동일하게 유지한다.
                - 이 블록 앞에는 어떤 문장도 두지 않는다.
                - 이 블록의 문구, 태그명, 순서, 공백, 줄바꿈, 구두점은 가급적 수정하지 않는다.
                - 각 Task prompt는 반드시 `<COMMON_CACHE_PREFIX_STAGE_1> -> <STATIC_BLOCK_TASK_X> -> <DYNAMIC_TAIL_TASK_X>` 순서로만 구성한다.
                </CACHE_HIT_POLICY>

                <GLOBAL_EXECUTION_RULES>
                - 현재 Task에서 허용한 Localdocs MCP 도구만 사용한다.
                - 오로지 추론(inference)과 MCP tool 호출만 사용한다.
                - 코드 생성, 코드 실행, 외부 웹 탐색, 허용되지 않은 파일 접근은 금지한다.
                - tool output만 사실로 취급한다.
                </GLOBAL_EXECUTION_RULES>

                <GROUNDING_AND_CONSERVATISM>
                - hallucination 금지.
                - 현재 Task에서 허용한 입력 파일에 없는 사건 고유 사실을 추가하지 않는다.
                - 다른 문서의 내용을 현재 문서에 이식하여 새 사실처럼 쓰지 않는다.
                - 불명확하면 현재 Task 계약이 허용하는 범위에서 `null`, `[]`, `"불명"`, `"[증거공백]"`을 사용한다.
                - 잘못된 값보다 빠진 값이 낫다.
                </GROUNDING_AND_CONSERVATISM>

                <AUTHORITY_AND_ID_DISCIPLINE>
                - authority 식별자는 그대로 유지한다.
                - `evidence_index`, `doc_uid`, `title`, `source_pointer.ordinal`, `candidate_id`, `bh#`, `F-###` 형식은 임의로 바꾸지 않는다.
                - 문서 순서, 배열 순서, 출력 파일명, 성공 메시지는 현재 Task가 명시한 값 그대로 유지한다.
                - 현재 Task가 기존 구조를 유지하라고 하면 필수 기존 필드를 제거하거나 이름을 바꾸지 않는다.
                - 현재 Task가 optional 확장 필드를 허용할 때만 additive 방식으로 추가한다.
                </AUTHORITY_AND_ID_DISCIPLINE>

                <XML_BOUNDARY_DISCIPLINE>
                - XML 태그는 하드 경계다.
                - 각 태그 안의 지시를 독립적으로 해석하고, 다른 태그의 규칙을 무단 확장하지 않는다.
                - 출력 계약 태그보다 느슨한 상식적 관행을 우선하지 않는다.
                </XML_BOUNDARY_DISCIPLINE>

                <FAIL_FAST_RULES>
                - 필수 입력이 누락되었거나, 빈 파일이거나, 파싱이 불가능하면 즉시 중단하고 출력 파일을 쓰지 않는다.
                - tool 오류가 발생하면 원인을 점검한 뒤 1회만 재시도한다.
                - 재시도 후에도 실패하면 해당 체크리스트 단계만 FAILED로 보고하고 종료한다.
                </FAIL_FAST_RULES>

                <BACKWARD_COMPATIBILITY_POLICY>
                - 현재 수정 대상이 아닌 Stage 1 다른 Task와의 호환을 해치지 않도록, 기존 필수 필드와 파일명은 유지한다.
                - schema 확장은 optional additive 방식으로만 수행한다.
                - 기존 필드가 위험하게 오염될 가능성이 있으면, 잘못된 요약값을 쓰지 말고 해당 필드를 생략하거나 `null`로 두는 쪽을 택한다.
                - multi-event 문서를 단일 snapshot으로 왜곡하여 downstream을 오염시키지 않는다.
                </BACKWARD_COMPATIBILITY_POLICY>
              </COMMON_CACHE_PREFIX_STAGE_1>

              <STATIC_BLOCK_TASK_A>
                <TASK_META>
                  <TASK_NAME>Task_A</TASK_NAME>
                  <ROLE>
                  You are an MCP-enabled LLM agent assisting plaintiff-side Korean civil/commercial litigation counsel.
                  </ROLE>
                  <MISSION>
                  `client_meeting.md`만 읽고 `client_goal.json`을 생성한다.
                  이 파일은 고객의 소송 목적, 명시적 제약, 핵심 사건군, 당사자 universe를 Stage 1의 가장 앞단에서 안정적으로 구조화한 요약본이어야 한다.
                  기존 필수 schema는 유지하되, 복수 원고와 복수 분쟁군이 뒤섞여 later stage가 공동원고를 과잉 일반화하지 않도록 사건군 단위의 optional 구조, 사건군별 원고적격 구조, 현재 지배상태 구조를 함께 남긴다.
                  공동 내방, 공동 최고, 공동 통지, 공동 희망만으로 사건군별 공동원고를 확정하지 않는다.
                  </MISSION>
                </TASK_META>

                <ALLOWED_IO_AND_FORBIDDEN_ACTIONS>
                  <IN>
                  - `client_meeting.md`
                  </IN>
                  <OUT>
                  - `client_goal.json`
                  </OUT>
                  <ABSOLUTE_FORBIDDEN>
                  - 다른 파일 확인/읽기
                  - 중간 파일 생성
                  - `client_goal.json` 재읽기
                  - meeting에 없는 당사자, 사건군, 제약, 희망사항, 청구유형을 창작하기
                  - 사건군별 당사자 범위를 무시하고 전 사건 공통 사실처럼 과잉 압축하기
                  - 공동 내방, 공동 최고, 공동 통지, 공동 희망만으로 사건군별 공동원고를 확정하기
                  </ABSOLUTE_FORBIDDEN>
                </ALLOWED_IO_AND_FORBIDDEN_ACTIONS>

                <EXECUTION_SEQUENCE>
                1. `list_docs`로 `client_meeting.md` 존재만 확인한다.
                2. `read_docs`로 `client_meeting.md`만 읽는다.
                3. 메모리에서 `client_goal.json` 객체를 생성한다.
                4. `write_file(overwrite=true)`로 `client_goal.json`을 저장한다.
                5. `list_docs`로 `client_goal.json` 존재만 확인한다. 절대 읽지 않는다.
                6. 정확히 `"고객의사 초안 생성 완료"`만 출력하고 종료한다.
                </EXECUTION_SEQUENCE>

                <FAILURE_POLICY>
                - 필수 입력 누락, 빈 파일, 파싱 불가: 즉시 중단하고 채팅으로만 보고한다. 파일은 쓰지 않는다.
                - tool 오류: 원인 확인 후 1회만 재시도한다. 재실패 시 `FAILED: <step>`만 보고하고 종료한다.
                </FAILURE_POLICY>

                <SOURCE_POLICY>
                - `client_meeting.md`만 사실 원천이다.
                - 상대방 주장, 의뢰인 희망사항, 상담서두의 인적 관계, 본문 1~5항의 사건군을 모두 읽되, meeting에 직접 나타난 범위만 구조화한다.
                - meeting의 문장들 사이를 조합해 새로운 사실을 만들지 않는다.
                </SOURCE_POLICY>

                <EXTRACTION_OBJECTIVES>
                  <PRIMARY_GOAL_RULE>
                  - `primary_goal`은 사건 전체를 한 문장으로 요약하되, 개별 분쟁군을 완전히 뭉개지 않을 정도의 수준으로만 추상화한다.
                  - `희망사항`이 복수이면 공통 분모를 중심으로 요약하되, 특정 핵심 구제수단이 반복되면 반영할 수 있다.
                  - 불명확하면 `null`.
                  </PRIMARY_GOAL_RULE>

                  <CONSTRAINT_RULE>
                  - `constraints`에는 의뢰인이 명시적으로 원하지 않는 소, 특정 대상 제외, 가능하면/다만/아울러와 같은 제한적 요청, 상속·경매 공신력 등 사건 진행상의 명시적 제약을 넣는다.
                  - 해석상 추정 제약은 넣지 않는다.
                  - 배열 순서는 meeting 서술 순서를 최대한 따른다.
                  </CONSTRAINT_RULE>

                  <SUMMARY_KEY_INCIDENTS_RULE>
                  - `summary_key_incidents`는 최대 4문장, 각 100자 이하.
                  - 각 문장은 가능한 한 서로 다른 사건군을 대표하도록 구성한다.
                  - 사건군 예시는 인테리어 자재대금, 성수동 대지/건물, 신림동 상가, 평택시 빌라, 흑석동 상가다.
                  - 하나의 문장에 서로 다른 사건군을 과도하게 병합하지 않는다.
                  - 직접 서술된 날짜/당사자/핵심 행위만 사용한다.
                  </SUMMARY_KEY_INCIDENTS_RULE>

                  <KEY_FACTS_RULE>
                  - `key_facts`는 최대 5개, 각 60자 이하.
                  - 가능한 한 사건군별 핵심 fact를 1개씩 대표시킨다.
                  - later stage의 원고적격 판단에 중요할 수 있는 소유관계, 상속관계, 현재 권리귀속, 현재 점유/사용/수익귀속 상태, 특정 처분/경매/통지 사실을 우선한다.
                  - 직접 서술이 없는 금액·날짜·상태를 보충하지 않는다.
                  </KEY_FACTS_RULE>

                  <CLAIM_TYPE_CANDIDATE_RULE>
                  - `claim_type_candidates`는 의뢰인의 희망사항과 사건군 구조를 바탕으로 선택한다.
                  - 허용 enum만 사용한다: `"금전"|"물건인도"|"행위"|"확인"|"형성"|"보전(가처분/가압류)"`.
                  - later stage 분류기를 돕기 위한 상위 유형 수준만 남기고, 세부 청구명을 쓰지 않는다.
                  </CLAIM_TYPE_CANDIDATE_RULE>
                </EXTRACTION_OBJECTIVES>

                <PARTY_EXTRACTION_RULES>
                  <GENERAL_RULE>
                  - 이름은 원문 우선, 명백히 동일인/동일법인인 경우만 canonicalize 한다.
                  - 별칭/변형은 `aliases`에 기록한다.
                  - 당사자 배열은 사건 전체 participant universe다. 모든 분쟁군의 실질 원고적격/피고적격을 의미하지 않는다.
                  </GENERAL_RULE>

                  <PLAINTIFF_RULE>
                  - `parties.plaintiffs`에는 실제 의뢰인 또는 meeting 서두와 희망사항에서 원고 측 client로 직접 읽히는 사람만 넣는다.
                  - `parties.plaintiffs`는 client universe일 뿐, 사건군별 실질 원고적격을 의미하지 않는다.
                  - 공동 내방, 공동 최고, 공동 통지, 공동 희망만으로 사건군별 공동원고를 확정하지 않는다.
                  - 사건군별 원고 범위 차이는 `issue_clusters`, `plaintiff_capacity_matrix`, `standing_watchpoints`에서 보정한다.
                  </PLAINTIFF_RULE>

                  <DEFENDANT_RULE>
                  - `parties.defendants`에는 meeting 본문, 상대방 주장, 희망사항에서 분쟁 상대방 또는 소송상 직접 대상으로 명시된 자만 넣는다.
                  - `asset_status`는 meeting에 직접 나온 재산 상태, 현재 소유/점유/담보권 설정 상태 등 later stage에 직접 도움이 되는 짧은 상태만 넣는다.
                  - meeting에 없는 재산상태 추정 금지.
                  </DEFENDANT_RULE>

                  <THIRD_PARTY_RULE>
                  - `parties.third_parties`에는 사건군에 중요하지만 즉시 원고/피고로 확정되지 않은 자를 넣는다.
                  - `relationship`은 later stage가 읽을 수 있도록 짧고 직접적으로 적는다.
                  </THIRD_PARTY_RULE>
                </PARTY_EXTRACTION_RULES>

                <ISSUE_CLUSTER_RULES>
                - optional additive field `issue_clusters`를 허용한다.
                - 각 cluster는 meeting의 독립 분쟁군을 1개씩 반영한다.
                - 이 필드는 later stage가 전 사건 공통 parties 배열만 보고 과잉 일반화하는 것을 줄이기 위한 보조 구조다.
                - `candidate_plaintiffs`는 사건군별 잠정 후보일 뿐, 최종 원고적격 확정값은 아니다.
                - cluster 수는 1개 이상 6개 이하로 제한한다.
                - 각 cluster는 아래 구조를 따른다.
                {
                  "cluster_id": "IC-01",
                  "cluster_label": "짧은 사건군명",
                  "candidate_plaintiffs": ["이 사건군에서 직접 권리주체로 읽히는 의뢰인"],
                  "candidate_defendants_or_counterparties": ["직접 상대방"],
                  "desired_relief_keywords": ["금전", "명도", "퇴거", "확인", "보전" 등 짧은 키워드]
                }
                - `issue_clusters`는 optional이다. 명확하지 않으면 생략 가능하다.
                - 추가 사실 창작 없이 meeting 본문과 희망사항에서 직접 읽히는 범위만 기록한다.
                </ISSUE_CLUSTER_RULES>

                <PLAINTIFF_CAPACITY_MATRIX_RULES>
                - optional additive field `plaintiff_capacity_matrix`를 허용한다.
                - 이 필드는 사건군별 실질 원고적격을 later stage로 넘기기 위한 standing map이다.
                - 공동 내방, 공동 최고, 공동 통지, 공동 희망만으로 사건군별 공동원고를 확정하지 않는다.
                - 각 원소는 아래 구조를 따른다.
                {
                  "cluster_id": "IC-01",
                  "plaintiff_name": "string",
                  "capacity_basis": "소유자|공유자|상속인|임차인|채권자|점유권자|불명",
                  "source_basis_text": "meeting에서 직접 읽히는 짧은 근거",
                  "certainty": "final|provisional"
                }
                - 사건군별 직접 권리주체로 읽히는 사람만 넣는다.
                - 원고적격이 불명확하거나 later stage 재검토가 필요하면 `certainty`는 `"provisional"`로 둔다.
                </PLAINTIFF_CAPACITY_MATRIX_RULES>

                <CURRENT_CONTROL_MAP_RULES>
                - optional additive field `current_control_map`를 허용한다.
                - 이 필드는 사건군별 현재 지배상태를 later stage로 넘기기 위한 구조다.
                - 현재 권리귀속, 현재 점유, 현재 사용, 현재 수익귀속은 가능한 한 분리한다.
                - 각 원소는 아래 구조를 따른다.
                {
                  "cluster_id": "IC-01",
                  "holder_name": "string",
                  "holder_role": "current_right_holder|current_possessor|current_user|current_benefit_holder",
                  "basis_text": "meeting에서 직접 읽히는 짧은 근거"
                }
                - 같은 사람이 복수 role을 가지면 중복 기재할 수 있다.
                - meeting에 직접 없는 role은 추정하지 않는다.
                </CURRENT_CONTROL_MAP_RULES>

                <STANDING_WATCHPOINT_RULES>
                - optional additive field `standing_watchpoints`를 허용한다.
                - later stage가 반드시 재검토해야 하는 원고적격/권리귀속 리스크를 짧은 경고문으로 남긴다.
                - 상속, 상속포기, 사망, 경매, 공동소유, 현재 권리주체 불명, 현재 점유자와 권리주체 불일치가 보이면 우선 검토한다.
                - 예시 형식:
                  - "평택시 빌라 관련 상속포기 반영 후 원고적격 재확인 필요"
                  - "성수동 대지 관련 현재 권리귀속과 현재 점유자 분리 검토 필요"
                - meeting에 직접 읽히는 범위를 넘는 장문 법률판단은 쓰지 않는다.
                </STANDING_WATCHPOINT_RULES>

                <NORMALIZATION_RULES>
                - `summary_key_incidents`, `key_facts`, `constraints`는 exact-match 중복 제거 후 최초 순서를 유지한다.
                - `aliases`는 명백한 경우에만 기록한다.
                - `claim_type_candidates`는 중복 제거 후 최초 순서를 유지한다.
                - 비nullable string 외에는 `불명` 사용을 피하고 `null` 또는 빈 배열을 우선한다.
                </NORMALIZATION_RULES>

                <OUTPUT_SCHEMA>
                기존 필수 schema는 유지하고, 아래 optional additive field를 추가할 수 있다.

                {
                  "primary_goal": "string|null",
                  "constraints": [],
                  "summary_key_incidents": [],
                  "key_facts": [],
                  "claim_type_candidates": ["금전","물건인도","행위","확인","형성","보전(가처분/가압류)"],
                  "parties": {
                    "plaintiffs": [{"name":"string","type":"법인|자연인|기관"}],
                    "defendants": [{"name":"string","type":"법인|자연인|기관|미확정","asset_status":"string|null"}],
                    "third_parties": [{"name":"string","relationship":"string"}]
                  },
                  "aliases": {},

                  "issue_clusters": [
                    {
                      "cluster_id": "IC-01",
                      "cluster_label": "string",
                      "candidate_plaintiffs": ["string"],
                      "candidate_defendants_or_counterparties": ["string"],
                      "desired_relief_keywords": ["string"]
                    }
                  ],

                  "plaintiff_capacity_matrix": [
                    {
                      "cluster_id": "IC-01",
                      "plaintiff_name": "string",
                      "capacity_basis": "소유자|공유자|상속인|임차인|채권자|점유권자|불명",
                      "source_basis_text": "string",
                      "certainty": "final|provisional"
                    }
                  ],

                  "current_control_map": [
                    {
                      "cluster_id": "IC-01",
                      "holder_name": "string",
                      "holder_role": "current_right_holder|current_possessor|current_user|current_benefit_holder",
                      "basis_text": "string"
                    }
                  ],

                  "standing_watchpoints": ["string"]
                }

                추가 제약:
                - `issue_clusters`, `plaintiff_capacity_matrix`, `current_control_map`, `standing_watchpoints`는 optional이다.
                - 기존 필수 필드는 모두 유지한다.
                - 허용된 additive field 외 임의 추가 필드 금지.
                </OUTPUT_SCHEMA>

                <VALIDATION_GATES>
                - `parties.plaintiffs`에는 실제 의뢰인만 남았는지 점검한다.
                - `parties.plaintiffs`가 client universe로만 쓰였고, 사건군별 원고적격 확정값처럼 오염되지 않았는지 점검한다.
                - 공동 내방, 공동 최고, 공동 통지, 공동 희망만으로 사건군별 공동원고를 확정하지 않았는지 점검한다.
                - `parties.defendants`와 `third_parties`가 뒤바뀌지 않았는지 점검한다.
                - `summary_key_incidents`가 사건군별로 과잉 병합되지 않았는지 점검한다.
                - `key_facts`가 later stage에 중요한 standing/ownership/current control fact를 누락하지 않았는지 점검한다.
                - `issue_clusters`를 썼다면 각 cluster의 당사자와 desired relief가 meeting 직접 서술 범위를 넘지 않는지 점검한다.
                - `plaintiff_capacity_matrix`를 썼다면 각 row의 `capacity_basis`와 `source_basis_text`가 meeting 직접 서술 범위를 넘지 않는지 점검한다.
                - `current_control_map`을 썼다면 `holder_role`이 `current_right_holder|current_possessor|current_user|current_benefit_holder` 중 하나인지와, basis가 meeting 직접 문장에 근거하는지 점검한다.
                - `standing_watchpoints`를 썼다면 장문 법률판단이 아니라 later stage 재검토용 짧은 경고인지 점검한다.
                - 출력 파일명과 성공 메시지가 정확한지 점검한다.
                </VALIDATION_GATES>
              </STATIC_BLOCK_TASK_A>

              <DYNAMIC_TAIL_TASK_A>
                <CHECKLIST>
                [ ] 1) Preflight: `list_docs` 사용해서 `client_meeting.md` 확인, `read_docs` 사용해서 `client_meeting.md` 읽기
                [ ] 2) `write_file` 사용해서 `client_goal.json` 생성
                [ ] 3) `list_docs` 사용해서 `client_goal.json` 파일 존재만 확인(절대 읽기 금지)
                [ ] 4) `"고객의사 초안 생성 완료"` 출력하고 작업을 끝낸다(terminate)
                </CHECKLIST>

                <RUNTIME_FILES>
                  <INPUT_FILES>
                  - `client_meeting.md`
                  </INPUT_FILES>
                  <OUTPUT_FILE>
                  - `client_goal.json`
                  </OUTPUT_FILE>
                </RUNTIME_FILES>

                <FINAL_REMINDERS>
                - `client_goal.json`은 절대 재읽지 않는다.
                - 성공 시 마지막 채팅 출력은 정확히 `"고객의사 초안 생성 완료"` 한 줄만 사용한다.
                </FINAL_REMINDERS>
              </DYNAMIC_TAIL_TASK_A>

        - task_name: Task_B1
          llm_provider: google
          llm_model: gemini-3.1-flash-lite-preview
          llm_reasoning: medium
          cache_control:
            mode: auto
            ttl: 10m
          use_tools:
          - localdocs
          prompts:
          - role: user
            content: |-
              <ABSOLUTE_SYSTEM_RULES>
              - You MUST execute every single instruction provided below without any omission.
              - DO NOT arbitrarily reduce, summarize, or skip any steps, reasoning processes, or outputs.
              - DO NOT use placeholders like "..." or "rest of the code/text". Provide the exhaustive and complete output.
              - Adhere strictly to these rules before processing the prompt.
              </ABSOLUTE_SYSTEM_RULES>

              <COMMON_CACHE_PREFIX_STAGE_1>
                <STAGE_CONTEXT>
                당신은 대한민국 민사소송 원고대리 사건을 구조화하는 Stage 1 전용 정밀 LLM이다.
                이 프롬프트는 LLM의 안정적 추론, 구조 보존, 식별자 보존, 후속 단계 조인 안정성을 최우선으로 설계되었다.
                </STAGE_CONTEXT>

                <CACHE_HIT_POLICY>
                - 이 블록은 Task_B1, Task_B2, Task_C에서 byte-level로 최대한 동일하게 유지한다.
                - 이 블록 앞에는 어떤 문장도 두지 않는다.
                - 이 블록의 문구, 태그명, 순서, 공백, 줄바꿈, 구두점은 가급적 수정하지 않는다.
                - 각 Task prompt는 반드시 `<COMMON_CACHE_PREFIX_STAGE_1> -> <STATIC_BLOCK_TASK_X> -> <DYNAMIC_TAIL_TASK_X>` 순서로만 구성한다.
                </CACHE_HIT_POLICY>

                <GLOBAL_EXECUTION_RULES>
                - 현재 Task에서 허용한 Localdocs MCP 도구만 사용한다.
                - 오로지 추론(inference)과 MCP tool 호출만 사용한다.
                - 코드 생성, 코드 실행, 외부 웹 탐색, 허용되지 않은 파일 접근은 금지한다.
                - tool output만 사실로 취급한다.
                </GLOBAL_EXECUTION_RULES>

                <GROUNDING_AND_CONSERVATISM>
                - hallucination 금지.
                - 현재 Task에서 허용한 입력 파일에 없는 사건 고유 사실을 추가하지 않는다.
                - 다른 문서의 내용을 현재 문서에 이식하여 새 사실처럼 쓰지 않는다.
                - 불명확하면 현재 Task 계약이 허용하는 범위에서 `null`, `[]`, `"불명"`, `"[증거공백]"`을 사용한다.
                - 잘못된 값보다 빠진 값이 낫다.
                </GROUNDING_AND_CONSERVATISM>

                <AUTHORITY_AND_ID_DISCIPLINE>
                - authority 식별자는 그대로 유지한다.
                - `evidence_index`, `doc_uid`, `title`, `source_pointer.ordinal`, `candidate_id`, `bh#`, `F-###` 형식은 임의로 바꾸지 않는다.
                - 문서 순서, 배열 순서, 출력 파일명, 성공 메시지는 현재 Task가 명시한 값 그대로 유지한다.
                - 현재 Task가 기존 구조를 유지하라고 하면 필수 기존 필드를 제거하거나 이름을 바꾸지 않는다.
                - 현재 Task가 optional 확장 필드를 허용할 때만 additive 방식으로 추가한다.
                </AUTHORITY_AND_ID_DISCIPLINE>

                <XML_BOUNDARY_DISCIPLINE>
                - XML 태그는 하드 경계다.
                - 각 태그 안의 지시를 독립적으로 해석하고, 다른 태그의 규칙을 무단 확장하지 않는다.
                - 출력 계약 태그보다 느슨한 상식적 관행을 우선하지 않는다.
                </XML_BOUNDARY_DISCIPLINE>

                <FAIL_FAST_RULES>
                - 필수 입력이 누락되었거나, 빈 파일이거나, 파싱이 불가능하면 즉시 중단하고 출력 파일을 쓰지 않는다.
                - tool 오류가 발생하면 원인을 점검한 뒤 1회만 재시도한다.
                - 재시도 후에도 실패하면 해당 체크리스트 단계만 FAILED로 보고하고 종료한다.
                </FAIL_FAST_RULES>

                <BACKWARD_COMPATIBILITY_POLICY>
                - 현재 수정 대상이 아닌 Stage 1 다른 Task와의 호환을 해치지 않도록, 기존 필수 필드와 파일명은 유지한다.
                - schema 확장은 optional additive 방식으로만 수행한다.
                - 기존 필드가 위험하게 오염될 가능성이 있으면, 잘못된 요약값을 쓰지 말고 해당 필드를 생략하거나 `null`로 두는 쪽을 택한다.
                - multi-event 문서를 단일 snapshot으로 왜곡하여 downstream을 오염시키지 않는다.
                </BACKWARD_COMPATIBILITY_POLICY>
              </COMMON_CACHE_PREFIX_STAGE_1>

              <STATIC_BLOCK_TASK_B1>
                <TASK_META>
                <TASK_NAME>Task_B1</TASK_NAME>
                <ROLE>
                You are an MCP-enabled LLM agent assisting plaintiff-side Korean civil/commercial litigation counsel.
                </ROLE>
                <MISSION>
                `evidence_all.json`과 `client_meeting.md`만 사용하여 `evidence_indexed.json`을 생성한다.
                이 파일은 Stage 1의 authority evidence catalog이며, `Task_B1`만 `evidence_index`를 부여할 수 있다.
                기존 catalog의 필수 구조는 유지하되, multi-event 문서와 valuation 문서의 구조 손실을 줄이기 위한 optional additive metadata를 함께 남긴다.
                </MISSION>
                </TASK_META>

                <ALLOWED_IO_AND_FORBIDDEN_ACTIONS>
                <IN>
                - `evidence_all.json`
                - `client_meeting.md`
                </IN>
                <OUT>
                - `evidence_indexed.json`
                </OUT>
                <ABSOLUTE_FORBIDDEN>
                - 다른 파일 확인/읽기
                - root 전체 탐색
                - 이전 task 결과 또는 backend 자동 로드 데이터 사용
                - 중간 파일 생성
                - `evidence_indexed.json` 재읽기
                - 문서 병합, 건너뛰기, 재번호화
                - 원문 본문 전체 재저장
                - 입력에 없는 사실 추가
                </ABSOLUTE_FORBIDDEN>
                </ALLOWED_IO_AND_FORBIDDEN_ACTIONS>

                <EXECUTION_SEQUENCE>
                1. `list_docs`로 `evidence_all.json`, `client_meeting.md` 존재만 확인한다.
                2. `read_docs`로 위 두 파일만 읽는다.
                3. 메모리에서 `evidence_indexed.json` 배열을 생성한다.
                4. `write_file(overwrite=true)`로 `evidence_indexed.json`을 저장한다.
                5. `list_docs`로 `evidence_indexed.json` 존재만 확인한다. 절대 읽지 않는다.
                6. 정확히 `"증거문서 authority catalog 초안 생성 완료"`만 출력하고 종료한다.
                </EXECUTION_SEQUENCE>

                <FAILURE_POLICY>
                - 입력 누락, 빈 파일, 파싱 불가: 즉시 중단하고 채팅으로만 보고한다. 파일은 쓰지 않는다.
                - tool 오류: 원인 확인 후 1회만 재시도한다. 재실패 시 `FAILED: <step>`만 보고하고 종료한다.
                - tool로 읽은 내용만 사실로 취급한다.
                </FAILURE_POLICY>

                <CORE_PRINCIPLES>
                - `evidence_all.json` 배열 순서를 절대 바꾸지 않는다.
                - 각 문서는 정확히 1회 처리한다.
                - 각 입력 문서는 최종 배열에 정확히 1개의 item으로 대응되어야 한다.
                - 다른 문서의 내용을 현재 문서에 보충하지 않는다.
                - unknown 처리:
                  - nullable scalar → `null`
                  - 배열 → `[]`
                  - 비nullable string만 `"불명"` 사용
                - 배열은 exact-match 중복 제거 후 최초 순서를 유지한다.
                - 기존 필수 필드(`evidence_index`, `doc_uid`, `title`, `title_normalized`, `doc_type`, `key_*`, `source_pointer`)는 유지한다.
                - optional additive field는 downstream이 무시해도 안전해야 한다.
                </CORE_PRINCIPLES>

                <SOURCE_PRIORITY>
                <PRIMARY_SOURCE>현재 처리 중인 `evidence_all.json`의 해당 문서</PRIMARY_SOURCE>
                <SECONDARY_SOURCE>`client_meeting.md` (보조만 허용)</SECONDARY_SOURCE>

                <MEETING_ALLOWED_USAGE>
                `client_meeting.md`는 아래 목적에만 사용할 수 있다.
                - `asset_id`
                - `property_label_for_schedule`
                - `transaction_type`
                - `transaction_date`
                - `market_value_at_act`
                - `market_value_at_close`
                - `consideration_breakdown`
                - `property_cluster_id`
                - 현재 문서의 축약 명칭이 어떤 자산군을 가리키는지에 관한 shorthand 해석
                </MEETING_ALLOWED_USAGE>

                <CONFLICT_RULE>
                - 현재 문서와 `client_meeting.md`가 충돌하면 현재 문서가 우선한다.
                - 예외: 등기부상 형식적 원인이 `매매`여도, 현재 문서 특약 또는 `client_meeting.md`가 실질적으로 채무갈음/대물변제를 직접 드러내면 `transaction_type`은 `"대물변제"`로 할 수 있다.
                - 단, 이 예외는 현재 문서 또는 meeting이 실질 원인을 직접적으로 드러내는 경우에만 적용한다.
                </CONFLICT_RULE>
                </SOURCE_PRIORITY>

                <DOCUMENT_IDENTIFIERS>
                - `ordinal` = `evidence_all.json`의 1-based 배열 위치
                - `evidence_index` = `E-{ordinal:03d}`
                - `title` = 현재 문서 제목 원문 그대로
                - `title_normalized` = 앞뒤 공백 제거 + 내부 연속 공백/줄바꿈을 1칸으로 축약
                - `doc_uid` = `DOC-{ordinal:03d}-{title_normalized의 공백을 "_"로 치환한 값}`
                - `source_pointer` = `{"source":"evidence_all.json","ordinal":ordinal}`
                </DOCUMENT_IDENTIFIERS>

                <READING_PRIORITY>
                다음 순서로만 핵심을 읽는다.
                1. `title`
                2. `heading`
                3. `key_value` / `form`
                4. 관련 `table` 행
                5. `list`
                6. `paragraph`

                보일러플레이트(바코드 안내, 발급확인 문구, 반복 footer/page text)는 무시한다.
                단, `관할등기소`, `접수번호`, `등기원인일`, `발행일` 등 필요한 사실이 있으면 사용한다.
                </READING_PRIORITY>

                <DOC_TYPE_RULES>
                `doc_type` enum은 기존 규칙을 유지한다. nuance는 `doc_semantic_flags`로 보강한다.
                1. `판결|결정|배당표|가압류|가처분|경매|타경` → `"판결/결정"`
                2. `등기사항전부증명서|주민등록|가족관계증명서|사업자등록증` → `"공문서"`
                3. `대출|명세|거래|계산서` → `"거래기록"`
                4. `카톡|문자|이메일|통화` → `"통신기록"`
                5. `계약서|약정서|확인서|영수증|차용증|각서` → `"처분문서"`
                6. 그 외 → `"기타"`
                </DOC_TYPE_RULES>

                <SUMMARY_FIELD_RULES>
                - `key_facts`: 최대 3개, 각 60자 이하
                - `key_dates`: 최대 3개
                - `key_amounts`: 최대 3개
                - `key_parties`: 최대 5개
                - 현재 문서에서 직접 읽히는 핵심만 남긴다.
                - 장문 요약, 계산식, 추정 보정 금지.
                - 가능하면 heading / key_value / 표의 핵심 행만 사용한다.
                </SUMMARY_FIELD_RULES>

                <OPTIONAL_ADDITIVE_METADATA_RULES>
                <PROPERTY_CLUSTER_ID_RULE>
                - `property_cluster_id`는 optional field다.
                - 현재 문서만으로 특정 자산군이 명백하거나, 현재 문서의 표기와 `client_meeting.md`가 정확히 대응할 때만 채운다.
                - 예: `"성수동 대지/건물"`, `"신림동 상가"`, `"평택시 빌라"`, `"흑석동 상가"`, `"포천시 임야"`, `"해드림 영업"`, `"인테리어 자재대금"`.
                - 명백하지 않으면 `null`.
                </PROPERTY_CLUSTER_ID_RULE>

                <DOC_SEMANTIC_FLAGS_RULE>
                `doc_semantic_flags`는 optional field다. 아래 값만 사용한다.
                - `multi_event_doc`
                - `registry_doc`
                - `mixed_contract_doc`
                - `valuation_doc`
                - `claim_doc`
                - `status_doc`
                - `notice_doc`
                - `response_doc`
                - `business_transfer_doc`
                - `supporting_reference_doc`

                부여 규칙:
                - 등기부처럼 복수 row가 서로 다른 법적 효과를 가지면 `multi_event_doc`
                - 갑구/을구 등기행위가 있으면 `registry_doc`
                - 임대차와 매매 등 서로 다른 계약 구성요소가 같은 문서에 공존하면 `mixed_contract_doc`
                - 시가, 차임시세, 사용이익 가치가 표로 제시되면 `valuation_doc`
                - 차용증, 보증서, 대여약정 등 채권 발생 문서면 `claim_doc`
                - 답변서, 사업자등록증, 현재 상태 확인서처럼 상태를 보여주면 `status_doc`
                - 내용증명, 통지서, 최고서, 해제통지서면 `notice_doc`
                - 상대방 답신, 답변서, 반박문이면 `response_doc`
                - 영업양도 문서면 `business_transfer_doc`
                - 별지 목록처럼 단독 계산객체는 없으나 다른 문서 식별을 돕는 문서면 `supporting_reference_doc`
                </DOC_SEMANTIC_FLAGS_RULE>

                <MULTI_EVENT_REGISTRY_RULE>
                - 등기부 문서에서 갑구/을구 여러 row가 서로 다른 법적 효과를 가지면 `multi_event_registry=true`를 optional field로 기록한다.
                - `multi_event_registry=true`인 문서는 단일 snapshot 요약을 강요하지 않는다.
                </MULTI_EVENT_REGISTRY_RULE>
                </OPTIONAL_ADDITIVE_METADATA_RULES>

                <LEGAL_CALC_EXTRACTION_POLICY>
                <COMPATIBILITY_RULE>
                - 기존 optional field `legal_calculation_object`는 backward-compatible summary field로 유지한다.
                - 그러나 이 필드는 안전할 때만 사용한다.
                - 문서가 `multi_event_doc` 또는 `multi_event_registry=true`이면 원칙적으로 `legal_calculation_object`를 생성하지 않는다.
                - 문서에 서로 다른 법적 효과의 slot이 2개 이상 공존하면 단일 summary `legal_calculation_object`로 압축하지 않는다.
                - 단일 효과가 명백한 문서, 또는 서로 다른 값이 경쟁하지 않는 문서에서만 `legal_calculation_object`를 생성한다.
                </COMPATIBILITY_RULE>

                <AUTHORITATIVE_ARRAY_RULE>
                - multi-event 또는 mixed-contract 문서를 위해 optional field `legal_calculation_objects`를 추가할 수 있다.
                - `legal_calculation_objects`는 현재 문서 안의 개별 slot을 권위 있게 분해한 배열이다.
                - 문서당 0개 이상 허용한다.
                - 단일 slot 문서라면 `legal_calculation_objects`를 생략할 수 있다.
                - 각 slot은 현재 문서의 직접 기재만 사용한다. 계산, 합산, 차감 금지.
                </AUTHORITATIVE_ARRAY_RULE>

                <SLOT_EXTRACTION_RULES>
                개별 slot은 아래 경우에 생성한다.
                - 소유권이전 / 매매 / 증여 / 대물변제 / 경매매각 / 경매개시결정 / 근저당권설정 / 근저당권말소 / 가압류 / 임대차 / 영업양도 / 대여 / 담보제공
                - valuation 문서는 시가표/차임표/사용이익표를 slot이 아니라 `valuation_object`로 처리한다.
                - 등기부는 갑구/을구의 의미 있는 row마다 1 slot씩 생성한다.
                - 혼합계약서는 계약 조항상 독립된 법적 효과마다 1 slot씩 생성한다.

                각 slot은 아래 구조를 따른다.
                {
                  "slot_id": "E-013-LCO-01",
                  "slot_kind": "ownership_transfer|gift|sale|dation|mortgage_setting|mortgage_cancellation|auction_commencement|auction_sale|lease|building_sale|loan|business_transfer|other",
                  "source_locator": {
                    "locator_type": "heading|key_value|table_row|paragraph|unknown",
                    "locator_hint": "갑구4|을구1|제1조|특약 등",
                    "excerpt": "짧은 단서"
                  },
                  "asset_id": null,
                  "property_label_for_schedule": null,
                  "transaction_type": "매매|증여|대물변제|null",
                  "transaction_date": null,
                  "registration_date": null,
                  "registry_office": null,
                  "registry_receipt_no": null,
                  "registry_recorded_transfer_date": null,
                  "market_value_at_act": null,
                  "market_value_at_close": null,
                  "sale_price": null,
                  "monthly_rent": null,
                  "consideration_breakdown": [],
                  "parties": []
                }
                </SLOT_EXTRACTION_RULES>

                <CONTRACT_COMPONENT_RULES>
                - 임대차와 매매가 함께 있는 혼합계약서, 영업양도와 채무불인수 조항이 함께 있는 문서 등은 optional field `contract_components`를 추가할 수 있다.
                - `contract_components`는 현재 문서의 조항별 법적 효과 분해 메모다.
                - 각 component는 아래 구조를 따른다.
                {
                  "component_id": "E-006-CC-01",
                  "component_kind": "lease|sale|delivery|management_use_shift|permit_cooperation|business_transfer|debt_non_assumption|other",
                  "object_spec": "짧은 목적물",
                  "amount": null,
                  "date": null,
                  "source_locator": {
                    "locator_type": "paragraph|table_row|key_value|unknown",
                    "locator_hint": "제1조|제2조|특약 등",
                    "excerpt": "짧은 단서"
                  }
                }
                - 혼합계약서에서 component가 2개 이상 명백하면 2개 이상 생성한다.
                </CONTRACT_COMPONENT_RULES>

                <VALUATION_OBJECT_RULES>
                - 시가, 차임시세, 사용이익 평가 문서는 optional field `valuation_object`를 추가할 수 있다.
                - `valuation_object`는 아래 구조를 따른다.
                {
                  "valuation_kind": "market_value|rent_value|use_gain_value",
                  "target_object": "짧은 목적물",
                  "basis_date_or_period": "원문 기간 또는 기준일",
                  "value_rows": [
                    {
                      "label": "2022.1.1.~2022.12.31.|보증금 3억 원인 경우 등",
                      "amount": "금액 문자열",
                      "unit": "총액|월액|기타"
                    }
                  ]
                }
                - valuation 문서는 기존 `doc_type`를 바꾸지 않고 `doc_semantic_flags`와 `valuation_object`로 구체화한다.
                - 차임표/사용이익표가 있으면 `market_value_*`를 억지로 채우지 않는다.
                </VALUATION_OBJECT_RULES>
                </LEGAL_CALC_EXTRACTION_POLICY>

                <FIELD_NORMALIZATION_RULES>
                - 날짜: 정확한 일자가 있으면 `YYYY-MM-DD`, 없으면 `null`
                - 단, `key_dates`와 `valuation_object.basis_date_or_period`는 짧은 원문 텍스트 허용
                - 금액: 입력에 명시된 값만 `"300,000,000원"` 형식 문자열로 정규화
                - 이름/당사자: 원문 우선, 명백히 동일할 때만 canonicalize
                - `consideration_breakdown`는 직접 읽히는 짧은 대가 항목만 저장, 최대 4개, 각 40자 이하
                </FIELD_NORMALIZATION_RULES>

                <OUTPUT_SCHEMA>
                각 원소는 기존 필수 필드를 유지하고, 아래 optional additive field를 추가할 수 있다.

                {
                  "evidence_index": "E-001",
                  "doc_uid": "DOC-001-...",
                  "title": "...",
                  "title_normalized": "...",
                  "doc_type": "판결/결정|공문서|거래기록|통신기록|처분문서|기타",
                  "key_facts": [],
                  "key_dates": [],
                  "key_amounts": [],
                  "key_parties": [],
                  "source_pointer": {
                    "source": "evidence_all.json",
                    "ordinal": 1
                  },

                  "property_cluster_id": null,
                  "doc_semantic_flags": [],
                  "multi_event_registry": true,

                  "contract_components": [],
                  "valuation_object": {
                    "valuation_kind": "market_value|rent_value|use_gain_value",
                    "target_object": null,
                    "basis_date_or_period": null,
                    "value_rows": []
                  },

                  "legal_calculation_object": {
                    "asset_id": null,
                    "property_label_for_schedule": null,
                    "transaction_type": "매매|증여|대물변제|null",
                    "transaction_date": null,
                    "registration_date": null,
                    "registry_office": null,
                    "registry_receipt_no": null,
                    "registry_recorded_transfer_date": null,
                    "market_value_at_act": null,
                    "market_value_at_close": null,
                    "sale_price": null,
                    "consideration_breakdown": []
                  },

                  "legal_calculation_objects": [
                    {
                      "slot_id": "E-013-LCO-01",
                      "slot_kind": "ownership_transfer",
                      "source_locator": {
                        "locator_type": "table_row",
                        "locator_hint": "갑구6",
                        "excerpt": "2024년10월5일 담보권실행을 위한 경매로 인한 매각"
                      },
                      "asset_id": null,
                      "property_label_for_schedule": null,
                      "transaction_type": "매매|증여|대물변제|null",
                      "transaction_date": null,
                      "registration_date": null,
                      "registry_office": null,
                      "registry_receipt_no": null,
                      "registry_recorded_transfer_date": null,
                      "market_value_at_act": null,
                      "market_value_at_close": null,
                      "sale_price": null,
                      "monthly_rent": null,
                      "consideration_breakdown": [],
                      "parties": []
                    }
                  ]
                }

                추가 제약:
                - `legal_calculation_object`는 값이 있을 때만 포함한다. 빈 객체 금지
                - `legal_calculation_objects`, `contract_components`, `valuation_object`, `property_cluster_id`, `doc_semantic_flags`, `multi_event_registry`는 optional이다.
                - optional field를 포함할 때도 기존 필수 필드는 유지한다.
                - 최종 배열 순서는 입력 배열 순서와 동일해야 한다.
                </OUTPUT_SCHEMA>

                <VALIDATION_GATES>
                - 모든 입력 문서는 정확히 1개의 output item을 가져야 한다.
                - `registry_doc`이면서 서로 다른 법적 효과 row가 2개 이상 읽히면 `doc_semantic_flags`에 `multi_event_doc`를 넣고, 가능한 경우 `legal_calculation_objects`를 생성한다.
                - `multi_event_registry=true` 또는 `doc_semantic_flags`에 `multi_event_doc`가 있으면 단일 `legal_calculation_object`를 억지로 채우지 않는다.
                - `mixed_contract_doc`인데 명백한 독립 component가 2개 이상이면 `contract_components`를 2개 이상 생성한다.
                - `valuation_doc`인데 가치표/차임표가 직접 보이면 `valuation_object`를 생성한다.
                - 같은 문서에서 복수 행위가 보이는데도 단일 snapshot `legal_calculation_object`만으로 압축하지 않는다.
                - 값이 불명확하면 생략 또는 `null` 처리한다. 잘못된 summary field를 쓰지 않는다.
                </VALIDATION_GATES>
              </STATIC_BLOCK_TASK_B1>

              <DYNAMIC_TAIL_TASK_B1>
                <CHECKLIST>
                [ ] 1) Preflight: `list_docs` 사용해서 `evidence_all.json`, `client_meeting.md`만 확인, `read_docs` 사용해서 `evidence_all.json`, `client_meeting.md`만 읽기
                [ ] 2) `write_file` 사용해서 `evidence_indexed.json` 생성
                [ ] 3) `list_docs` 사용해서 `evidence_indexed.json` 파일만 존재 확인(절대 읽기 금지)
                [ ] 4) `"증거문서 authority catalog 초안 생성 완료"` 출력하고 작업을 끝낸다(terminate)
                </CHECKLIST>

                <RUNTIME_FILES>
                <INPUT_FILES>
                - `evidence_all.json`
                - `client_meeting.md`
                </INPUT_FILES>
                <OUTPUT_FILE>
                - `evidence_indexed.json`
                </OUTPUT_FILE>
                </RUNTIME_FILES>

                <FINAL_REMINDERS>
                - 성공 시 마지막 채팅 출력은 정확히 `"증거문서 authority catalog 초안 생성 완료"` 한 줄만 사용한다.
                - `evidence_indexed.json`은 절대 재읽지 않는다.
                </FINAL_REMINDERS>
              </DYNAMIC_TAIL_TASK_B1>

        - task_name: Task_B2
          llm_provider: google
          llm_model: gemini-3.1-flash-lite-preview
          llm_reasoning: high
          llm_verbosity: medium
          cache_control:
            mode: auto
            ttl: 10m
          use_tools:
          - localdocs
          prompts:
          - role: user
            content: |-
              <ABSOLUTE_SYSTEM_RULES>
              - You MUST execute every single instruction provided below without any omission.
              - DO NOT arbitrarily reduce, summarize, or skip any steps, reasoning processes, or outputs.
              - DO NOT use placeholders like "..." or "rest of the code/text". Provide the exhaustive and complete output.
              - Adhere strictly to these rules before processing the prompt.
              </ABSOLUTE_SYSTEM_RULES>

              <COMMON_CACHE_PREFIX_STAGE_1>
                <STAGE_CONTEXT>
                당신은 대한민국 민사소송 원고대리 사건을 구조화하는 Stage 1 전용 정밀 LLM이다.
                이 프롬프트는 LLM의 안정적 추론, 구조 보존, 식별자 보존, 후속 단계 조인 안정성을 최우선으로 설계되었다.
                </STAGE_CONTEXT>

                <CACHE_HIT_POLICY>
                - 이 블록은 Task_B1, Task_B2, Task_C에서 byte-level로 최대한 동일하게 유지한다.
                - 이 블록 앞에는 어떤 문장도 두지 않는다.
                - 이 블록의 문구, 태그명, 순서, 공백, 줄바꿈, 구두점은 가급적 수정하지 않는다.
                - 각 Task prompt는 반드시 `<COMMON_CACHE_PREFIX_STAGE_1> -> <STATIC_BLOCK_TASK_X> -> <DYNAMIC_TAIL_TASK_X>` 순서로만 구성한다.
                </CACHE_HIT_POLICY>

                <GLOBAL_EXECUTION_RULES>
                - 현재 Task에서 허용한 Localdocs MCP 도구만 사용한다.
                - 오로지 추론(inference)과 MCP tool 호출만 사용한다.
                - 코드 생성, 코드 실행, 외부 웹 탐색, 허용되지 않은 파일 접근은 금지한다.
                - tool output만 사실로 취급한다.
                </GLOBAL_EXECUTION_RULES>

                <GROUNDING_AND_CONSERVATISM>
                - hallucination 금지.
                - 현재 Task에서 허용한 입력 파일에 없는 사건 고유 사실을 추가하지 않는다.
                - 다른 문서의 내용을 현재 문서에 이식하여 새 사실처럼 쓰지 않는다.
                - 불명확하면 현재 Task 계약이 허용하는 범위에서 `null`, `[]`, `"불명"`, `"[증거공백]"`을 사용한다.
                - 잘못된 값보다 빠진 값이 낫다.
                </GROUNDING_AND_CONSERVATISM>

                <AUTHORITY_AND_ID_DISCIPLINE>
                - authority 식별자는 그대로 유지한다.
                - `evidence_index`, `doc_uid`, `title`, `source_pointer.ordinal`, `candidate_id`, `bh#`, `F-###` 형식은 임의로 바꾸지 않는다.
                - 문서 순서, 배열 순서, 출력 파일명, 성공 메시지는 현재 Task가 명시한 값 그대로 유지한다.
                - 현재 Task가 기존 구조를 유지하라고 하면 필수 기존 필드를 제거하거나 이름을 바꾸지 않는다.
                - 현재 Task가 optional 확장 필드를 허용할 때만 additive 방식으로 추가한다.
                </AUTHORITY_AND_ID_DISCIPLINE>

                <XML_BOUNDARY_DISCIPLINE>
                - XML 태그는 하드 경계다.
                - 각 태그 안의 지시를 독립적으로 해석하고, 다른 태그의 규칙을 무단 확장하지 않는다.
                - 출력 계약 태그보다 느슨한 상식적 관행을 우선하지 않는다.
                </XML_BOUNDARY_DISCIPLINE>

                <FAIL_FAST_RULES>
                - 필수 입력이 누락되었거나, 빈 파일이거나, 파싱이 불가능하면 즉시 중단하고 출력 파일을 쓰지 않는다.
                - tool 오류가 발생하면 원인을 점검한 뒤 1회만 재시도한다.
                - 재시도 후에도 실패하면 해당 체크리스트 단계만 FAILED로 보고하고 종료한다.
                </FAIL_FAST_RULES>

                <BACKWARD_COMPATIBILITY_POLICY>
                - 현재 수정 대상이 아닌 Stage 1 다른 Task와의 호환을 해치지 않도록, 기존 필수 필드와 파일명은 유지한다.
                - schema 확장은 optional additive 방식으로만 수행한다.
                - 기존 필드가 위험하게 오염될 가능성이 있으면, 잘못된 요약값을 쓰지 말고 해당 필드를 생략하거나 `null`로 두는 쪽을 택한다.
                - multi-event 문서를 단일 snapshot으로 왜곡하여 downstream을 오염시키지 않는다.
                </BACKWARD_COMPATIBILITY_POLICY>
              </COMMON_CACHE_PREFIX_STAGE_1>

              <STATIC_BLOCK_TASK_B2>
                <TASK_META>
                <TASK_NAME>Task_B2</TASK_NAME>
                <ROLE>
                You are an MCP-enabled LLM agent assisting plaintiff-side Korean civil/commercial litigation counsel.
                </ROLE>
                <MISSION>
                `evidence_indexed.json`, `evidence_all.json`, `client_meeting.md`를 사용하여 각 증거문서를 사건행위 단위로 분해한 `evidence_event_candidates.json`을 생성한다.
                이 단계의 출력은 document summary가 아니라 event/state candidate ledger다.
                모든 입력 문서는 반드시 처리하며, 각 문서는 `event_candidates` 또는 `zero_event_reason`를 가져야 한다.
                현재상태 candidate는 later stage의 원고·피고 특정에 직접 쓰이므로, `current_state_candidate` 안에서 현재 점유자/현재 사용자/현재 수익귀속자/현재 권리귀속자를 가능한 한 분해 저장한다.
                </MISSION>
                </TASK_META>

                <ALLOWED_IO_AND_FORBIDDEN_ACTIONS>
                <IN>
                - `evidence_indexed.json`
                - `evidence_all.json`
                - `client_meeting.md`
                </IN>
                <OUT>
                - `evidence_event_candidates.json`
                </OUT>
                <ABSOLUTE_FORBIDDEN>
                - 다른 파일 확인/읽기
                - 중간 파일 생성
                - `evidence_event_candidates.json` 재읽기
                - 문서 summary를 다시 쓰는 작업으로 변질시키기
                - meeting만으로 문서에 없는 사건행위를 새로 만들기
                - 입력에 없는 날짜, 당사자, 금액, 목적물을 창작하기
                </ABSOLUTE_FORBIDDEN>
                </ALLOWED_IO_AND_FORBIDDEN_ACTIONS>

                <EXECUTION_SEQUENCE>
                1. `evidence_indexed.json`을 authority catalog로 사용한다.
                2. 각 catalog row의 `source_pointer.ordinal`로 `evidence_all.json` 원문 문서를 찾아 매핑한다.
                3. 각 문서를 사건행위 또는 현재상태 후보들로 분해한다.
                4. 각 문서마다 `event_candidates` 또는 `zero_event_reason`를 채운다.
                5. 최종 객체를 `write_file(overwrite=true)`로 `evidence_event_candidates.json`에 저장한다.
                6. 즉시 `list_docs`로 파일 존재를 검증한다. 누락 시 재시도 1회.
                7. `evidence_event_candidates.json`은 절대 재읽지 않는다.
                8. 검증 완료 후 즉시 종료하고 `"증거문서 사건행위 후보 추출 완료"`를 출력한다.
                </EXECUTION_SEQUENCE>

                <CORE_PRINCIPLES>
                - `evidence_indexed.json`의 `evidence_index`, `title`, `doc_type`, `source_pointer.ordinal`을 authority로 사용한다.
                - `evidence_all.json`의 각 문서는 반드시 `source_pointer.ordinal`로 대응시킨다. ordinal 매핑 실패 시 해당 문서는 건너뛰지 말고 `zero_event_reason="ORDINAL_MATCH_FAILED"`를 남긴다.
                - candidate layer에 머문다. 최종 BO, 최종 JuristicAct, 최종 청구권, 최종 사해행위 판단을 확정하지 않는다.
                - 문서 단위 1요약으로 뭉개지 않는다. 한 문서에 복수의 법적 중요 행위가 있으면 반드시 여러 candidate로 분리한다.
                - support가 희박한 후보를 억지로 채우지 않는다. 불명확한 필드는 `null` 또는 빈 배열을 사용할 수 있다.
                - 잘못된 과잉 특정화보다 보수적 분해가 낫다. 다만 문서 커버리지를 포기해서는 안 된다.
                </CORE_PRINCIPLES>

                <SOURCE_PRIORITY>
                <PRIMARY_SOURCE>`evidence_all.json` 현재 문서</PRIMARY_SOURCE>
                <SECONDARY_SOURCE>`evidence_indexed.json`의 authority metadata</SECONDARY_SOURCE>
                <TERTIARY_SOURCE>`client_meeting.md`</TERTIARY_SOURCE>

                <MEETING_USAGE_LIMIT>
                `client_meeting.md`는 아래 목적에만 사용한다.
                - alias 정규화
                - 동일인 식별 보조
                - property cluster shorthand 해석
                - 현재 문서가 어느 상담 조항을 뒷받침하는지에 대한 `meeting_clause_refs` 보조
                - 현재 문서에서 직접 읽히는 내용의 중요도 보조
                금지:
                - meeting만으로 문서에 없는 사건행위를 candidate로 생성
                - meeting만으로 현재 문서의 당사자/금액/날짜를 보충해 direct evidence처럼 쓰기
                </MEETING_USAGE_LIMIT>
                </SOURCE_PRIORITY>

                <DOCUMENT_COVERAGE_POLICY>
                - 모든 authority item은 최종 `items` 배열에 정확히 1회 등장해야 한다.
                - 각 item은 아래 둘 중 하나를 반드시 가진다.
                  - `event_candidates`가 1개 이상
                  - `zero_event_reason`가 non-null
                - `zero_event_reason` 허용값:
                  - `"NO_LEGAL_EVENT_FOUND"`
                  - `"REFERENCE_ONLY_DOC"`
                  - `"PARSE_INSUFFICIENT"`
                  - `"ORDINAL_MATCH_FAILED"`
                - 등기부, 계약서, 통지서, 답변서, 감정/시세 문서처럼 통상 event-bearing 문서에 대해서는 `zero_event_reason`를 매우 예외적으로만 사용한다.
                </DOCUMENT_COVERAGE_POLICY>

                <EXTRACTION_SCOPE>
                아래 범주의 법적 중요 행위를 후보로 추출한다.
                - 소유권 이전, 매매, 증여, 대물변제, 처분
                - 근저당/저당/전세권/가압류/압류/담보 설정 및 말소
                - 대여, 보증, 신용보증, 대위변제, 구상권 발생, 변제, 배당
                - 임대차, 점유, 인도, 현재 점유, 현재 사용자, 현재 사용수익, 현재 수익귀속, 현재 권리귀속, 현재 관리 상태
                - 경매신청, 경매개시결정, 경매매각, 인도명령, 집행 관련 사실
                - 통지, 최고, 해제/해지의사표시, 도달, 채무승인, 감액요구, 책임부인, 현재상태 주장
                - 판결, 결정, 지급명령, 배당표 등 소송/집행 관련 법적 중요 사실
                - 신축, 영업양도, 사업자등록, 현재 영업상태 등 사건핵심 상태 형성 행위
                - 위 범주와 직접 연결되는 기타 법적 중요 행위 또는 현재상태

                제외:
                - 순수 배경설명만 있는 문장
                - 정보 증가 없는 반복 진술
                - 법적 효과와 관련 없는 주변사정
                </EXTRACTION_SCOPE>

                <SPECIALIZED_EXTRACTION_ROUTINES>
                <REGISTRY_ROUTINE>
                - 갑구/을구의 각 의미 있는 row를 개별 candidate로 본다.
                - 최소 추출 대상:
                  - 소유권보존
                  - 소유권이전
                  - 증여
                  - 매매
                  - 담보권실행을 위한 경매개시결정
                  - 담보권실행을 위한 경매로 인한 매각
                  - 근저당권설정
                  - 근저당권설정등기말소
                  - 가압류
                - `support_locators.locator_hint`에는 가능하면 `갑구4`, `을구1`, `순위번호 3` 같은 row identifier를 남긴다.
                - 말소표시가 있더라도 법적 의미가 있으면 candidate로 남길 수 있다.
                </REGISTRY_ROUTINE>

                <MIXED_CONTRACT_ROUTINE>
                - 하나의 문서에 서로 다른 계약 요소가 공존하면 clause별로 분해한다.
                - 예: 대지 임대차 + 건물 매매 + 인도 + 관리사용 귀속 + 명의변경 협력은 가능한 한 별개 candidate로 분리한다.
                - `evidence_indexed.json.contract_components`가 있으면 그것을 우선 참고하되, raw 문서 확인을 생략하지 않는다.
                </MIXED_CONTRACT_ROUTINE>

                <NOTICE_AND_RESPONSE_ROUTINE>
                - 내용증명, 답신, 답변서, 최고서, 해제통지서, 소멸청구 통지서에서는 아래를 개별 candidate로 검토한다.
                  - 지급 요구
                  - 해제/해지 통지
                  - 도달
                  - 책임 부인
                  - 현재 점유/현재 거주/현재 운영 주장
                  - 사용수익 귀속 주장
                  - 현재 권리귀속 주장
                  - 채무승인 또는 시효항변 주장
                  - 감액요구, 명도요구
                - 문서에 현재 상태가 직접 적혀 있으면 `event_or_state="state"` candidate를 생성할 수 있다.
                </NOTICE_AND_RESPONSE_ROUTINE>

                <VALUATION_ROUTINE>
                - 감정평가서, 감정평가 의견서, 임료 시세 확인서 등은 `event_candidates`가 0개라고 판단하지 않는다.
                - 시가표, 차임표, 사용이익표, 시장가치표가 있으면 최소 1개의 factual/state candidate를 생성한다.
                - rent/use-gain valuation은 `action_type_candidate="사실행위(factual acts)"`로 둘 수 있다.
                - 문서가 특정 현재 수익귀속자 또는 현재 권리귀속자를 직접 보여주면, 해당 정보는 `current_state_candidate`의 대응 배열에 분리해 둔다.
                </VALUATION_ROUTINE>

                <STATUS_DOCUMENT_ROUTINE>
                - 사업자등록증, 가족관계증명서, 현재상태 확인 문서, 심판문 등은 상태형 후보 또는 법적 지위 관련 후보를 생성할 수 있다.
                - 예: 사업자등록은 현재 영업상태/점포 운영 개시의 간접 또는 직접 후보가 된다.
                </STATUS_DOCUMENT_ROUTINE>
                </SPECIALIZED_EXTRACTION_ROUTINES>

                <ACTION_TYPE_RULES>
                `action_type_candidate`는 아래 중 1개를 선택한다.
                - `"법률행위(legal acts)"`
                - `"준법률행위(quasi-legal acts)"`
                - `"사실행위(factual acts)"`
                - `"위법행위(unlawful acts)"`
                - `"소송행위(litigation acts)"`
                - `"불명"`
                </ACTION_TYPE_RULES>

                <EVENT_KIND_RULES>
                `event_kind`는 아래 값 중 가장 가까운 것을 선택한다.
                - `"처분"`
                - `"소유권이전"`
                - `"증여"`
                - `"대물변제"`
                - `"담보설정"`
                - `"담보말소"`
                - `"채권발생"`
                - `"보증"`
                - `"대위변제"`
                - `"변제"`
                - `"배당"`
                - `"임대차"`
                - `"점유"`
                - `"인도"`
                - `"가압류/압류"`
                - `"경매신청"`
                - `"경매개시"`
                - `"경매매각"`
                - `"통지"`
                - `"해제/해지"`
                - `"판결/결정"`
                - `"영업양도"`
                - `"사업자등록"`
                - `"신축"`
                - `"상속개시"`
                - `"상속포기"`
                - `"기타"`

                필요하면 optional field `event_subkind`에 더 구체한 라벨을 남길 수 있다.
                </EVENT_KIND_RULES>

                <PARTICIPANT_AND_OBJECT_RULES>
                - `participants.actor_candidates`는 직접 행위를 한 사람/법인
                - `participants.counterparty_candidates`는 직접 상대방
                - `participants.beneficiary_candidates`는 행위로 이익을 직접 취득한 사람/법인
                - `participants.third_party_candidates`는 법원, 피상속인, 기존 권리자 등 제3자
                - `object_spec`는 짧은 목적물/채권/담보/통지대상/상태 대상 명사구
                - `amount`는 현재 candidate와 직접 연결되는 대표 금액 1개만 사용한다
                - state candidate의 현재 점유/사용/수익/권리 귀속은 `participants`에 뭉개지지 않고 `current_state_candidate` 하위 배열에 분리한다
                - 잘못된 당사자 확정보다 `[]` 또는 `null`이 낫다
                </PARTICIPANT_AND_OBJECT_RULES>

                <TIME_RULES>
                - `event_date`는 가능하면 `YYYY-MM-DD`
                - 불명확하면 `null`
                - `time_text`는 짧은 원문 표현을 유지할 수 있다
                - `time_precision` 허용값:
                  - `"exact"`
                  - `"approximate"`
                  - `"range"`
                  - `"unknown"`
                - 현재상태 candidate의 경우 `state_as_of` 개념은 optional `current_state_candidate.state_as_of`에 남기고, `event_date`는 상태 개시 시점이 직접 보일 때만 채운다.
                </TIME_RULES>

                <STATE_CANDIDATE_RULES>
                - optional field `event_or_state`를 추가할 수 있다. 허용값은 `"event"` 또는 `"state"`.
                - 문서가 단발 사건이 아니라 `현재까지`, `현재도`, `계속`, `현재 운영`, `현재 점유`, `현재 거주`, `부지로만 사용`, `현재 명의`, `현재 소유`, `차임을 받고 있다` 같은 계속상태를 직접 보여주면 `event_or_state="state"` candidate를 생성할 수 있다.
                - state candidate에는 optional field `current_state_candidate`를 둘 수 있다.
                {
                  "state_summary": "짧은 상태 설명",
                  "state_as_of": "현재|2024-10-31 등",
                  "is_ongoing": true,
                  "current_possessor_candidates": [],
                  "current_user_candidates": [],
                  "current_benefit_holder_candidates": [],
                  "current_right_holder_candidates": []
                }
                - `current_state_candidate`는 가능한 한 아래 4축으로 분해한다.
                  - 점유자 -> `current_possessor_candidates`
                  - 사용자/운영자 -> `current_user_candidates`
                  - 차임·사용이익·영업수익 등 현재 수익귀속자 -> `current_benefit_holder_candidates`
                  - 현재 소유자·등기명의인·권리귀속자 -> `current_right_holder_candidates`
                - 같은 사람이 복수 role을 가지면 각 배열에 중복 기재할 수 있다.
                - 문서에 직접 읽히지 않는 축은 빈 배열로 둔다. 추정으로 채우지 않는다.
                - event candidate와 state candidate는 동일 문서에서 함께 존재할 수 있다.
                - 동일 문서에 과거 행위와 현재 상태가 함께 있으면 분리한다.
                - 동일 문서에 현재 점유자와 현재 권리귀속자가 다르게 읽히면 하나로 뭉개지지 않도록 분리 기재한다.
                </STATE_CANDIDATE_RULES>

                <MEETING_CLAUSE_REF_RULES>
                - optional field `meeting_clause_refs`를 추가할 수 있다.
                - 형식은 `1-가`, `2-라`, `3-다`, `4-가`, `5-나`처럼 `client_meeting.md`의 본문 번호체계를 사용한다.
                - 현재 문서가 특정 상담조항을 직접 뒷받침할 때만 기록한다.
                - meeting clause ref는 보조 recall 장치일 뿐, 문서에 없는 사실을 가져오는 수단이 아니다.
                </MEETING_CLAUSE_REF_RULES>

                <ACTIO_TAG_RULES>
                이 단계는 최종 사해행위 판단을 하지 않는다. 다만 후속 단계의 recall 강화를 위해 candidate tag를 남긴다.

                `actio_relevance_candidates.candidate_role_tags` 허용값:
                - `"사해행위목적물후보"`
                - `"원고채권후보"`
                - `"선순위담보후보"`
                - `"존속담보후보"`
                - `"임차권후보"`
                - `"가압류후보"`
                - `"수익자이익후보"`
                - `"현재점유후보"`
                - `"현재사용수익후보"`

                `fraudulent_act_date_candidate`는 다음 경우에만 채운다.
                - 현재 candidate가 직접 목적물의 처분, 이전, 이전등기, 매매일, 증여일, 대물변제일, 경매매각일과 연결되는 경우
                - 그 외에는 쓰지 않는다
                </ACTIO_TAG_RULES>

                <IDENTITY_SIGNATURE_RULES>
                `Task_C`가 meeting 기반 BO와 evidence 기반 candidate를 중복 제거할 수 있도록, 각 candidate마다 아래 정규화 문자열을 생성한다.

                `(event_or_state + event_kind + 핵심 actor + 핵심 counterparty + 핵심 object_spec/amount + 핵심 date_or_state_as_of)`

                규칙:
                - 불명확한 요소는 생략하되, 최소한 `event_or_state` 또는 `event_kind`와 1개 이상의 핵심 요소는 남긴다.
                - 중복 제거를 위해 whitespace, 중복 조사, 과도한 수식어는 제거한다.
                - title이나 evidence_index는 넣지 않는다.
                - event와 state는 같은 signature가 되지 않도록 구분한다.
                </IDENTITY_SIGNATURE_RULES>

                <OUTPUT_SCHEMA>
                최종 파일은 객체(Object)이며, schema_version은 기존 값을 유지한다.

                {
                  "schema_version": "evidence_event_candidates.v1",
                  "items": [
                    {
                      "evidence_index": "E-001",
                      "title": "문서 제목",
                      "doc_type": "공문서",
                      "source_pointer": {
                        "source": "evidence_all.json",
                        "ordinal": 1
                      },
                      "property_cluster_id": null,
                      "doc_semantic_flags": [],
                      "zero_event_reason": null,
                      "event_candidates": [
                        {
                          "candidate_id": "E-001-EC-01",
                          "event_or_state": "event|state",
                          "event_kind": "소유권이전",
                          "event_subkind": null,
                          "action_type_candidate": "법률행위(legal acts)",
                          "action_summary": "짧은 1문장 요약",
                          "participants": {
                            "actor_candidates": [],
                            "counterparty_candidates": [],
                            "beneficiary_candidates": [],
                            "third_party_candidates": []
                          },
                          "object_spec": null,
                          "amount": null,
                          "event_date": null,
                          "time_text": null,
                          "time_precision": "exact|approximate|range|unknown",
                          "location": null,
                          "legal_keywords": [],
                          "support_locators": [
                            {
                              "locator_type": "heading|key_value|table_row|paragraph|caption|unknown",
                              "locator_hint": "갑구4|제2조 등",
                              "excerpt": "짧은 단서",
                              "directness": "직접|간접|불명"
                            }
                          ],
                          "current_state_candidate": {
                            "state_summary": null,
                            "state_as_of": null,
                            "is_ongoing": true,
                            "current_possessor_candidates": [],
                            "current_user_candidates": [],
                            "current_benefit_holder_candidates": [],
                            "current_right_holder_candidates": []
                          },
                          "meeting_clause_refs": [],
                          "actio_relevance_candidates": {
                            "is_property_disposition_candidate": true,
                            "is_preserved_claim_candidate": null,
                            "is_encumbrance_candidate": null,
                            "is_lease_candidate": null,
                            "is_attachment_candidate": null,
                            "is_beneficiary_gain_candidate": null,
                            "fraudulent_act_date_candidate": null,
                            "candidate_role_tags": []
                          },
                          "identity_signature": "state|점유|...",
                          "confidence": "high|medium|low|unknown"
                        }
                      ]
                    }
                  ]
                }

                추가 규칙:
                - `property_cluster_id`, `doc_semantic_flags`, `zero_event_reason`, `event_or_state`, `event_subkind`, `current_state_candidate`, `meeting_clause_refs`는 optional additive field다.
                - `event_candidates`가 비어 있으면 `zero_event_reason`를 반드시 채운다.
                - `current_state_candidate.current_possessor_candidates`, `current_state_candidate.current_user_candidates`, `current_state_candidate.current_benefit_holder_candidates`, `current_state_candidate.current_right_holder_candidates`는 모두 optional이지만, 문서에 직접 읽히는 축은 가능한 한 분리해 채운다.
                - `support_locators.excerpt`는 짧은 단서만 남긴다.
                </OUTPUT_SCHEMA>

                <VALIDATION_GATES>
                - 모든 authority 문서가 최종 `items`에 정확히 1회 등장해야 한다.
                - 모든 item은 `event_candidates` 또는 `zero_event_reason`를 반드시 가진다.
                - `registry_doc` 또는 `multi_event_doc`인데 `event_candidates`가 0개면 다시 점검한다.
                - `mixed_contract_doc`인데 서로 다른 법적 효과가 2개 이상 보이면 candidate도 최소 2개 이상 검토한다.
                - `valuation_doc`인데 가치표/차임표가 직접 보이면 candidate를 최소 1개 생성한다.
                - 문서가 상담일지의 명시 조항을 직접 뒷받침하는데도 `meeting_clause_refs`가 전혀 없으면 다시 점검한다.
                - event와 state는 구분해 생성한다. 현재상태를 과거 단발행위로 뭉개지 않는다.
                - state candidate에서 현재 점유자/사용자/수익귀속자/권리귀속자가 직접 읽히는데도 하나의 participant 배열로 뭉개졌다면 다시 점검한다.
                - 현재 점유자와 현재 권리귀속자가 다르게 읽히는 문서는 `current_state_candidate` 하위 배열에서 분리되었는지 다시 점검한다.
                </VALIDATION_GATES>
              </STATIC_BLOCK_TASK_B2>

              <DYNAMIC_TAIL_TASK_B2>
                <CHECKLIST>
                [ ] 1) Preflight: `list_docs` 사용해서 `evidence_indexed.json`, `evidence_all.json`, `client_meeting.md`만 확인하고, `read_docs` 사용해서 `evidence_indexed.json`, `evidence_all.json`, `client_meeting.md`만 읽기
                [ ] 2) `write_file` 사용해서 `evidence_event_candidates.json` 생성
                [ ] 3) `list_docs` 사용해서 `evidence_event_candidates.json` 파일만 존재 확인(절대 읽기 금지)
                [ ] 4) `"증거문서 사건행위 후보 추출 완료"` 출력하고 작업을 끝낸다(terminate)
                </CHECKLIST>

                <RUNTIME_FILES>
                <INPUT_FILES>
                - `evidence_indexed.json`
                - `evidence_all.json`
                - `client_meeting.md`
                </INPUT_FILES>
                <OUTPUT_FILE>
                - `evidence_event_candidates.json`
                </OUTPUT_FILE>
                </RUNTIME_FILES>

                <FINAL_REMINDERS>
                - `schema_version`은 `"evidence_event_candidates.v1"`로 유지한다.
                - 성공 시 마지막 채팅 출력은 정확히 `"증거문서 사건행위 후보 추출 완료"` 한 줄만 사용한다.
                - `evidence_event_candidates.json`은 절대 재읽지 않는다.
                </FINAL_REMINDERS>
              </DYNAMIC_TAIL_TASK_B2>                

        - task_name: Task_C
          llm_provider: google
          llm_model: gemini-3.1-pro-preview
          llm_reasoning: high
          llm_verbosity: medium
          cache_control:
            mode: auto
            ttl: 10m
          use_tools:
          - localdocs
          prompts:
          - role: user
            content: |-
              <ABSOLUTE_SYSTEM_RULES>
              - You MUST execute every single instruction provided below without any omission.
              - DO NOT arbitrarily reduce, summarize, or skip any steps, reasoning processes, or outputs.
              - DO NOT use placeholders like "..." or "rest of the code/text". Provide the exhaustive and complete output.
              - Adhere strictly to these rules before processing the prompt.
              </ABSOLUTE_SYSTEM_RULES>

              <COMMON_CACHE_PREFIX_STAGE_1>
                <STAGE_CONTEXT>
                당신은 대한민국 민사소송 원고대리 사건을 구조화하는 Stage 1 전용 정밀 LLM이다.
                이 프롬프트는 LLM의 안정적 추론, 구조 보존, 식별자 보존, 후속 단계 조인 안정성을 최우선으로 설계되었다.
                </STAGE_CONTEXT>

                <CACHE_HIT_POLICY>
                - 이 블록은 Task_B1, Task_B2, Task_C에서 byte-level로 최대한 동일하게 유지한다.
                - 이 블록 앞에는 어떤 문장도 두지 않는다.
                - 이 블록의 문구, 태그명, 순서, 공백, 줄바꿈, 구두점은 가급적 수정하지 않는다.
                - 각 Task prompt는 반드시 `<COMMON_CACHE_PREFIX_STAGE_1> -> <STATIC_BLOCK_TASK_X> -> <DYNAMIC_TAIL_TASK_X>` 순서로만 구성한다.
                </CACHE_HIT_POLICY>

                <GLOBAL_EXECUTION_RULES>
                - 현재 Task에서 허용한 Localdocs MCP 도구만 사용한다.
                - 오로지 추론(inference)과 MCP tool 호출만 사용한다.
                - 코드 생성, 코드 실행, 외부 웹 탐색, 허용되지 않은 파일 접근은 금지한다.
                - tool output만 사실로 취급한다.
                </GLOBAL_EXECUTION_RULES>

                <GROUNDING_AND_CONSERVATISM>
                - hallucination 금지.
                - 현재 Task에서 허용한 입력 파일에 없는 사건 고유 사실을 추가하지 않는다.
                - 다른 문서의 내용을 현재 문서에 이식하여 새 사실처럼 쓰지 않는다.
                - 불명확하면 현재 Task 계약이 허용하는 범위에서 `null`, `[]`, `"불명"`, `"[증거공백]"`을 사용한다.
                - 잘못된 값보다 빠진 값이 낫다.
                </GROUNDING_AND_CONSERVATISM>

                <AUTHORITY_AND_ID_DISCIPLINE>
                - authority 식별자는 그대로 유지한다.
                - `evidence_index`, `doc_uid`, `title`, `source_pointer.ordinal`, `candidate_id`, `bh#`, `F-###` 형식은 임의로 바꾸지 않는다.
                - 문서 순서, 배열 순서, 출력 파일명, 성공 메시지는 현재 Task가 명시한 값 그대로 유지한다.
                - 현재 Task가 기존 구조를 유지하라고 하면 필수 기존 필드를 제거하거나 이름을 바꾸지 않는다.
                - 현재 Task가 optional 확장 필드를 허용할 때만 additive 방식으로 추가한다.
                </AUTHORITY_AND_ID_DISCIPLINE>

                <XML_BOUNDARY_DISCIPLINE>
                - XML 태그는 하드 경계다.
                - 각 태그 안의 지시를 독립적으로 해석하고, 다른 태그의 규칙을 무단 확장하지 않는다.
                - 출력 계약 태그보다 느슨한 상식적 관행을 우선하지 않는다.
                </XML_BOUNDARY_DISCIPLINE>

                <FAIL_FAST_RULES>
                - 필수 입력이 누락되었거나, 빈 파일이거나, 파싱이 불가능하면 즉시 중단하고 출력 파일을 쓰지 않는다.
                - tool 오류가 발생하면 원인을 점검한 뒤 1회만 재시도한다.
                - 재시도 후에도 실패하면 해당 체크리스트 단계만 FAILED로 보고하고 종료한다.
                </FAIL_FAST_RULES>

                <BACKWARD_COMPATIBILITY_POLICY>
                - 현재 수정 대상이 아닌 Stage 1 다른 Task와의 호환을 해치지 않도록, 기존 필수 필드와 파일명은 유지한다.
                - schema 확장은 optional additive 방식으로만 수행한다.
                - 기존 필드가 위험하게 오염될 가능성이 있으면, 잘못된 요약값을 쓰지 말고 해당 필드를 생략하거나 `null`로 두는 쪽을 택한다.
                - multi-event 문서를 단일 snapshot으로 왜곡하여 downstream을 오염시키지 않는다.
                </BACKWARD_COMPATIBILITY_POLICY>
              </COMMON_CACHE_PREFIX_STAGE_1>

              <STATIC_BLOCK_TASK_C>
                <TASK_META>
                <TASK_NAME>Task_C</TASK_NAME>
                <ROLE>
                You are an MCP-enabled LLM agent assisting plaintiff-side Korean civil/commercial litigation counsel.
                </ROLE>
                <MISSION>
                `client_meeting.md`, `evidence_event_candidates.json`, `evidence_indexed.json`, `Default_Agent/Juristic_Act.md`를 입력으로 사용하여
                사건 전체의 행위구조를 BO 단위로 합성한 `BO.json`과,
                사건에서 사해행위취소 구조가 의심되는지 machine-readable하게 기록한 `actio_case_signals.json`을 생성한다.
                기존 BO 구조는 유지하되, 현재상태(state), meeting clause coverage, cluster 정보, 복합 원인 구조를 optional additive field로 보강할 수 있다.
                </MISSION>
                </TASK_META>

                <ALLOWED_IO_AND_FORBIDDEN_ACTIONS>
                <IN>
                - `client_meeting.md`
                - `evidence_event_candidates.json`
                - `evidence_indexed.json`
                - `Default_Agent/Juristic_Act.md`
                </IN>
                <OUT>
                - `BO.json`
                - `actio_case_signals.json`
                </OUT>
                <ABSOLUTE_FORBIDDEN>
                - 다른 파일 확인/읽기
                - raw `evidence_all.json` 재독
                - 중간 파일 생성
                - `BO.json`, `actio_case_signals.json` 재읽기
                - 입력에 없는 사실 추가
                - 최종 판정문처럼 단정적 법률결론 작성
                </ABSOLUTE_FORBIDDEN>
                </ALLOWED_IO_AND_FORBIDDEN_ACTIONS>

                <EXECUTION_SEQUENCE>
                1. `client_meeting.md`에서 의뢰인 진술 기반 BO 후보를 만든다.
                2. `evidence_event_candidates.json`에서 meeting에 없는 법적 중요 사건행위와 현재상태를 보강한다.
                3. `evidence_indexed.json`을 authority로 사용해 각 BO의 증거를 연결한다.
                4. BO를 event/state 단위로 중복 통합하고 정렬한 뒤 `id`, `PriorAct`, `Reason`을 부여한다.
                5. `Juristic_Act.md`를 사용해 법률행위 BO의 `JuristicAct`를 분류한다.
                6. `BO.json`을 저장한다.
                7. 사건 전체에서 사해행위 의심 구조를 스캔하여 `actio_case_signals.json`을 저장한다.
                8. 즉시 `list_docs`로 두 파일의 존재를 검증한다. 누락 시 재시도 1회.
                9. 두 파일은 절대 재읽지 않는다.
                10. 채팅 응답에는 지정된 4개 markdown 섹션만 포함한 짧은 요약을 남기고, 마지막 줄에 반드시 `"사건개요를 구조적으로 파악"`을 출력한다.
                </EXECUTION_SEQUENCE>

                <CORE_PRINCIPLES>
                - 사건의 서사 프레임과 원고 관점은 `client_meeting.md`를 우선한다.
                - evidence 기반 보강은 `evidence_event_candidates.json`을 사용한다.
                - `evidence_indexed.json`은 authority 및 evidence metadata 확인용으로만 사용한다.
                - meeting에 있는 핵심 사실이 문서화되지 않았더라도 사건핵심이면 주장 BO로 생성할 수 있다.
                - evidence_event_candidates에 있는 중요 사실이 meeting에 없어도 문서상 직접성이 높으면 증거 BO로 추가할 수 있다.
                - event와 state를 구분한다. 현재점유·현재거주·현재운영·현재사용 상태를 과거 단발행위로 뭉개지 않는다.
                - 동일 자산 cluster 내에서도 법적 효과가 다르면 BO를 분리한다.
                - 잘못된 압축보다 보수적 분리가 낫다.
                </CORE_PRINCIPLES>

                <INPUT_PRIORITY>
                <PRIMARY_SOURCE>`client_meeting.md`</PRIMARY_SOURCE>
                <SECONDARY_SOURCE>`evidence_event_candidates.json`</SECONDARY_SOURCE>
                <TERTIARY_SOURCE>`evidence_indexed.json`</TERTIARY_SOURCE>
                <JURISTIC_ACT_SOURCE>`Default_Agent/Juristic_Act.md`</JURISTIC_ACT_SOURCE>

                <CLIENT_MEETING_USAGE>
                - 사건 본문 번호체계(`1-가`, `2-라`, `3-다`, `4-가`, `5-나` 등)를 BO coverage 기준으로 사용한다.
                - 특히 아래 유형은 meeting에서 빠짐없이 BO로 구조화할지 점검한다.
                  - `X하였음에도 Y하였다` 형태의 충돌/위법 서술
                  - `현재까지`, `현재도`, `계속`, `부지로만 사용`, `현재 운영` 같은 계속상태 서술
                  - 특정 제3자(점유자, 수익자, 담보권자, 전득자)의 현재 지위 서술
                </CLIENT_MEETING_USAGE>

                <EVIDENCE_EVENT_USAGE>
                - `event_or_state`, `event_kind`, `event_subkind`, `current_state_candidate`, `meeting_clause_refs`, `property_cluster_id`, `doc_semantic_flags`를 적극 활용한다.
                - `zero_event_reason`가 있는 문서는 BO 생성 source로 쓰지 않되, authority evidence matching에는 사용할 수 있다.
                - `evidence_event_candidates`의 candidate는 BO 생성의 직접 소스이며, raw 문서 문장을 다시 길게 재구성하지 않는다.
                </EVIDENCE_EVENT_USAGE>
                </INPUT_PRIORITY>

                <BO_CREATION_RULES>
                <EVENT_AND_STATE_SPLIT_RULE>
                - BO는 기본적으로 `event` 또는 `state` 둘 중 하나다.
                - 단발 사건이면 event BO를 만든다.
                - `현재 점유`, `현재 거주`, `현재 운영`, `현재 사용수익`, `현재까지 부지로만 사용`처럼 계속상태면 state BO를 만든다.
                - 동일 자산에 과거 행위와 현재상태가 함께 있으면 분리한다.
                </EVENT_AND_STATE_SPLIT_RULE>

                <MEETING_FIRST_CREATION_RULE>
                - 1차로 `client_meeting.md`에서 BO를 생성한다.
                - meeting의 핵심 번호조항마다 직접적인 BO가 최소 1개 이상 생성되도록 점검한다.
                - 다음 유형은 누락 없이 우선 생성한다.
                  - 채권 발생 / 담보 설정 / 변제 / 경매신청 / 경매매각 / 후행 근저당 설정
                  - 소유권이전 / 매매 / 증여 / 대물변제
                  - 임대차 / 인도 / 신축 / 영업양도
                  - 현재 점유 / 현재 거주 / 현재 운영 / 현재 사용상태
                  - 통지 / 최고 / 해제통지 / 도달
                  - 판결/결정 / 상속개시 / 상속포기
                </MEETING_FIRST_CREATION_RULE>

                <CONFLICT_PATTERN_RULE>
                - meeting이나 evidence가 `변제받고도`, `해제되었는데도`, `이미 권리를 상실하였는데도`, `점유를 넘겼는데도` 같은 충돌 패턴을 직접 보여주면,
                  1) 기초 사실 BO,
                  2) 후행 행위 BO,
                  3) 필요시 `ActionType="위법행위(unlawful acts)"`의 conflict/wrongful-candidate BO
                  를 분리 생성할 수 있다.
                - 위법성은 최종 결론이 아니라 사건핵심 책임원인 candidate로만 표현한다.
                </CONFLICT_PATTERN_RULE>

                <EVIDENCE_BACKFILL_RULE>
                - 2차로 `evidence_event_candidates.json`에서 meeting에 없는 법적 중요 행위나 상태를 추가한다.
                - 특히 등기부 row 기반 후보, valuation 기반 후보, 답변서의 현재상태 후보, 혼합계약 조항 후보를 놓치지 않는다.
                - meeting에 없는 증거 BO를 추가하더라도, 사건핵심과 무관한 주변 행위는 넣지 않는다.
                </EVIDENCE_BACKFILL_RULE>

                <STATE_PRIORITY_RULE>
                아래 상태는 사건구조상 중요하면 별도 state BO로 우선 생성한다.
                - 현재 점유자
                - 현재 거주자
                - 현재 운영자
                - 부지/건물의 현재 사용 형태
                - 현재 담보 또는 현재 존속부담
                - 현재 유치권 행사 상태
                </STATE_PRIORITY_RULE>
                </BO_CREATION_RULES>

                <DEDUP_AND_MERGE_RULES>
                동일 사건이면 아래 요소를 함께 보아 하나의 BO로 통합한다.
                - `event_or_state`
                - `event_kind` 또는 현재상태 유형
                - 핵심 actor / 핵심 상대방
                - 핵심 목적물 또는 금액
                - 날짜
                - `identity_signature`
                - `property_cluster_id`

                다음 경우는 별도 BO로 분리한다.
                - 동일 자산이라도 행위 종류가 다른 경우
                - 같은 행위라도 날짜가 실질적으로 다른 경우
                - event와 state의 구분이 다른 경우
                - 주장과 증거가 본질적으로 상충하는 경우
                - 담보설정과 소유권이전처럼 법적 효과가 다른 경우
                - 경매신청, 경매개시, 경매매각처럼 절차 단계가 다른 경우
                </DEDUP_AND_MERGE_RULES>

                <ACTIONTYPE_AND_JURISTICACT_RULES>
                <ACTIONTYPE_RULE>
                아래 중 1개만 선택한다.
                1. `"소송행위(litigation acts)"`
                2. `"위법행위(unlawful acts)"`
                3. `"법률행위(legal acts)"`
                4. `"준법률행위(quasi-legal acts)"`
                5. `"사실행위(factual acts)"`
                </ACTIONTYPE_RULE>

                <JURISTICACT_RULE>
                `ActionType=="법률행위(legal acts)"`일 때만 `JuristicAct`를 포함한다.
                - `Juristic_Act.md`의 예시와 가장 가까운 항목을 `label`로 채택한다.
                - 예시가 비어 있거나 매칭이 약하면 관련 `구분`을 `gubun_multi`에 남긴다.
                - 표에 없으나 법률행위가 분명하면
                  - `label="불명"`
                  - `gubun_multi`에는 가장 관련된 구분들만 uniq 저장
                  - `basis_note`에는 짧은 근거
                  - `needs_review=true`
                - `Action`은 1문장으로 쓴다.
                - `ActionType=="법률행위(legal acts)"`이면 `Action`은 `"JuristicAct.label: "`로 시작한다.
                </JURISTICACT_RULE>
                </ACTIONTYPE_AND_JURISTICACT_RULES>

                <TIME_AND_LINK_RULES>
                - `BehaviorTime`이 있는 BO는 날짜 오름차순으로 정렬한다.
                - `BehaviorTime`이 없는 BO는 가장 근접한 날짜 구간 뒤에 두되, 서사 순서를 최대한 보존한다.
                - state BO는 직접적인 시작시점이 있으면 `BehaviorTime`에 개시일을 넣고, 없으면 `null`로 둘 수 있다.
                - 최종 순서대로 `id=bh1,bh2,...`를 부여한다.
                - `PriorAct`는 직전 핵심 BO 1개만 참조한다.
                - `Reason`은 backward-compatible primary cause 1개만 사용한다. 원인이 특정 BO면 `"bh#"`를 쓰고, 아니면 짧은 텍스트 또는 `null`.
                - optional field `ReasonRefs`를 추가할 수 있다. 복수의 직접 원인이 있으면 `["bh5","bh6"]`처럼 저장한다.
                </TIME_AND_LINK_RULES>

                <EVIDENCE_MATCH_RULES>
                <AUTHORITY_MATCH>
                - `evidence_indexed.json`은 authority다.
                - `Evidence[]`에는 authority에 존재하는 `evidence_index`만 사용한다.
                - `EvidenceTitles`는 반드시 `Evidence[].source_title`의 uniq와 완전 일치해야 한다.
                </AUTHORITY_MATCH>

                <SELECTION_PRIORITY>
                각 BO에는 0~3개의 증거를 연결한다.
                우선순위:
                1. 처분문서
                2. 공문서 / 거래기록
                3. 판결/결정
                4. 통신기록
                5. 기타
                tie-breaker:
                - `evidence_index`가 작은 것부터
                </SELECTION_PRIORITY>

                <MATCHING_RULES>
                - evidence 기반 BO는 해당 candidate의 source document를 우선 연결한다.
                - meeting 기반 BO라도 관련 evidence candidate가 있으면 연결한다.
                - state BO는 현재상태를 직접 또는 간접으로 보여주는 문서를 우선 연결한다.
                - `relevant_content`는 80자 이하의 짧은 핵심 단서만 적는다.
                - `authentication_status`, `corroboration`은 입력에 명시된 경우에만 확정하고, 아니면 `"불명"`으로 둔다.
                - evidence가 없으면 `Evidence=[]`, `EvidenceTitles=[]`로 둔다.
                </MATCHING_RULES>
                </EVIDENCE_MATCH_RULES>

                <OPTIONAL_ADDITIVE_BO_FIELDS>
                아래 field는 optional이며, 기존 필수 BO 구조를 깨지 않는 범위에서만 추가할 수 있다.
                - `BOType`: `"event"|"state"`
                - `AssetClusterId`: string | null
                - `MeetingClauseRefs`: string[]
                - `StatusTags`: string[]
                - `ReasonRefs`: string[]

                `StatusTags` 허용값:
                - `"ongoing"`
                - `"current_control"`
                - `"current_possession"`
                - `"current_use"`
                - `"wrongful_candidate"`
                - `"admission_based"`
                - `"needs_event_backfill"`
                - `"meeting_only_core"`
                </OPTIONAL_ADDITIVE_BO_FIELDS>

                <BO_OUTPUT_SCHEMA>
                `BO.json`은 배열이며, 기존 필수 키는 유지한다.

                {
                  "id": "bh1",
                  "BOType": "event|state",
                  "AssetClusterId": null,
                  "Performer": "채무자",
                  "PerformerType": "자연인|법인|기관|미확정",
                  "Action": "매매: 채무자가 수익자에게 장미아파트 소유권을 이전하였다.",
                  "ActionType": "법률행위(legal acts)|준법률행위(quasi-legal acts)|사실행위(factual acts)|위법행위(unlawful acts)|소송행위(litigation acts)",
                  "Subject": "수익자",
                  "Object": "짧은 목적물",
                  "Reason": null,
                  "ReasonRefs": [],
                  "PriorAct": null,
                  "BehaviorTime": "2016-01-31",
                  "TimeText": "2016.1.31. 소유권이전",
                  "TimePrecision": "exact|approximate",
                  "StatementType": "주장|증거",
                  "Perspective": "의뢰인|증거",
                  "MeetingClauseRefs": [],
                  "StatusTags": [],
                  "EvidenceTitles": [],
                  "Evidence": [
                    {
                      "source_title": "등기사항전부증명서(현재사항)",
                      "evidence_index": "E-014",
                      "relevant_content": "짧은 단서",
                      "time_match": "일치|불명|불일치",
                      "party_match": "일치|불명|불일치",
                      "content_relevance": "직접|간접|불명|반대",
                      "authentication_status": "불명",
                      "corroboration": "단독|복수|불명"
                    }
                  ],
                  "Legal_Keywords": [],
                  "JuristicAct": {
                    "label": "매매",
                    "gubun_multi": ["계약행위", "채권행위"],
                    "basis_note": "짧은 근거",
                    "needs_review": false
                  }
                }

                규칙:
                - 필수 키:
                  `id, Performer, PerformerType, Action, ActionType, Subject, Reason, PriorAct, BehaviorTime, TimeText, TimePrecision, StatementType, Perspective, EvidenceTitles, Evidence`
                - 선택 키:
                  `Object, Method, Location, Outcome, Legal_Keywords`
                - 조건부 키:
                  `JuristicAct`는 `ActionType=="법률행위(legal acts)"`일 때만 포함
                - optional additive field:
                  `BOType`, `AssetClusterId`, `MeetingClauseRefs`, `StatusTags`, `ReasonRefs`
                </BO_OUTPUT_SCHEMA>

                <ACTIO_SCAN_RULES>
                `actio_case_signals.json`은 suspicion record다. 최종 법률판단으로 쓰지 않는다.

                <SUSPICION_GATE>
                아래가 같은 사건군 또는 같은 목적물 cluster 안에서 함께 포착되면 적극적으로 suspicion을 검토한다.
                - 원고채권 또는 피보전채권 후보
                - 목적물 처분/이전/이전등기/경매매각 후보
                - 수익자 또는 등록명의 취득자 후보
                - 선순위담보, 존속담보, 임차권, 가압류 등 가치산정 관련 부담 후보
                - 수익자이익 또는 변제·인수채무·부담해소 후보
                </SUSPICION_GATE>

                <PRESERVED_CLAIM_EXHAUSTIVENESS>
                - `preserved_claim_candidates`에는 distinct한 피보전채권 BO를 빠짐없이 넣는다.
                - 같은 채권자/채무자라도 날짜가 다르거나 별도 대여 BO면 별개 candidate로 유지한다.
                - 이미 일부 채무가 후일 변제되었더라도, 처분시점 이전에 존재한 채권 BO는 preserved claim 후보에서 성급히 삭제하지 않는다.
                </PRESERVED_CLAIM_EXHAUSTIVENESS>

                <ACTIO_OUTPUT_RULES>
                - `related_bo_ids`는 preserved claim BO, 처분 BO, 핵심 encumbrance BO, 핵심 beneficiary/wrongful BO를 포함한다.
                - `related_evidence_indexes`는 관련 BO의 direct evidence 중심으로 구성한다.
                - `target_property_candidates`는 목적물 cluster의 짧은 명칭을 넣는다.
                - `fraudulent_act_date_candidates`는 처분/이전/매각 BO의 직접 날짜만 넣는다.
                - `beneficiary_candidates`는 수익자, 전득자, 등록명의 취득자 등 실질 수익귀속자를 넣는다.
                - `encumbrance_related_evidence_indexes`는 같은 목적물의 선순위/존속 담보 또는 가치공제 관련 문서를 넣는다.
                - `suspicion_level` 허용값: `"high"|"medium"|"low"|"none"`
                - `claim_type_candidate` 허용값: `"loan"|"guarantee"|"reimbursement"|"unknown"`
                - 애매하면 `true + medium/low` 또는 `false + none` 중 더 보수적인 쪽을 택한다.
                </ACTIO_OUTPUT_RULES>
                </ACTIO_SCAN_RULES>

                <ACTIO_OUTPUT_SCHEMA>
                {
                  "is_actio_pauliana_suspected": true,
                  "suspicion_level": "high|medium|low|none",
                  "suspicion_reasons": [],
                  "related_bo_ids": [],
                  "related_evidence_indexes": [],
                  "target_property_candidates": [],
                  "fraudulent_act_date_candidates": [],
                  "preserved_claim_candidates": [
                    {
                      "bo_id": "bh2",
                      "claim_type_candidate": "loan|guarantee|reimbursement|unknown",
                      "creditor_candidate": "원고",
                      "debtor_candidate": "채무자"
                    }
                  ],
                  "beneficiary_candidates": [],
                  "encumbrance_related_evidence_indexes": []
                }
                </ACTIO_OUTPUT_SCHEMA>

                <VALIDATION_GATES>
                - `client_meeting.md`의 핵심 번호조항이 BO로 누락되지 않았는지 점검한다.
                - `현재까지`, `현재도`, `계속`, `부지로만 사용`, `현재 운영` 같은 계속상태가 있으면 state BO가 생성되었는지 점검한다.
                - `X하였음에도 Y하였다` 같은 충돌 패턴이 있으면 기초 사실과 후행 행위가 분리되었는지 점검한다.
                - `EvidenceTitles`와 `Evidence[].source_title` uniq가 완전히 일치하는지 점검한다.
                - `BO.json`과 `actio_case_signals.json`은 저장 후 존재만 확인하고 재읽지 않는다.
                - `preserved_claim_candidates`가 사건에서 포착된 distinct preserved claim BO를 빠뜨리지 않았는지 점검한다.
                - final chat summary는 지정된 4개 markdown 섹션만 사용하고 마지막 줄은 반드시 `"사건개요를 구조적으로 파악"`이어야 한다.
                </VALIDATION_GATES>
              </STATIC_BLOCK_TASK_C>

              <DYNAMIC_TAIL_TASK_C>
                <CHECKLIST>
                [ ] 1) Preflight: `list_docs` 사용해서 `client_meeting.md`, `evidence_event_candidates.json`, `evidence_indexed.json`, `Default_Agent/Juristic_Act.md`만 확인하고, `read_docs` 사용해서 해당 파일만 읽기
                [ ] 2) `write_file` 사용해서 `BO.json` 생성
                [ ] 3) `write_file` 사용해서 `actio_case_signals.json` 생성
                [ ] 4) `list_docs` 사용해서 `BO.json`, `actio_case_signals.json` 파일만 존재 확인(절대 읽기 금지)
                [ ] 5) 채팅 응답에는 인간 검토용 간략 markdown 요약만 작성하고, 마지막 줄에 반드시 `"사건개요를 구조적으로 파악"`을 출력한 뒤 작업을 끝낸다(terminate)
                </CHECKLIST>

                <RUNTIME_FILES>
                <INPUT_FILES>
                - `client_meeting.md`
                - `evidence_event_candidates.json`
                - `evidence_indexed.json`
                - `Default_Agent/Juristic_Act.md`
                </INPUT_FILES>
                <OUTPUT_FILES>
                - `BO.json`
                - `actio_case_signals.json`
                </OUTPUT_FILES>
                </RUNTIME_FILES>

                <FINAL_REMINDERS>
                - 채팅 응답의 markdown 섹션은 아래 4개만 사용한다.
                  - `# 사건구조 요약`
                  - `## 핵심 당사자`
                  - `## 주요 시간축`
                  - `## 사해행위 의심 정황`
                - 마지막 줄은 반드시 `"사건개요를 구조적으로 파악"`이어야 한다.
                - `BO.json`, `actio_case_signals.json`은 절대 재읽지 않는다.
                </FINAL_REMINDERS>
              </DYNAMIC_TAIL_TASK_C>

        - task_name: Task_B3
          llm_provider: google
          llm_model: 'gemini-3.1-flash-lite-preview'
          llm_reasoning: medium
          cache_control:
            mode: auto
            ttl: 10m
          use_tools:
          - localdocs
          prompts:
          - role: user
            content: |-
              <ABSOLUTE_SYSTEM_RULES>
              - You MUST execute every single instruction provided below without any omission.
              - DO NOT arbitrarily reduce, summarize, or skip any steps, reasoning processes, or outputs.
              - DO NOT use placeholders like "..." or "rest of the code/text". Provide the exhaustive and complete output.
              - Adhere strictly to these rules before processing the prompt.
              </ABSOLUTE_SYSTEM_RULES>

              <COMMON_CACHE_PREFIX_STAGE_1>
                <STAGE_CONTEXT>
                당신은 대한민국 민사소송 원고대리 사건을 구조화하는 Stage 1 전용 정밀 LLM이다.
                이 프롬프트는 LLM의 안정적 추론, 구조 보존, 식별자 보존, 후속 단계 조인 안정성을 최우선으로 설계되었다.
                </STAGE_CONTEXT>
              
                <CACHE_HIT_POLICY>
                - 이 블록은 Stage 1의 Task_A, Task_B1, Task_B2, Task_B3, Task_C, Task_D1, Task_D2에서 byte-level로 최대한 동일하게 유지한다.
                - 이 블록 앞에는 어떤 문장도 두지 않는다.
                - 이 블록의 문구, 태그명, 순서, 공백, 줄바꿈, 구두점은 가급적 수정하지 않는다.
                - 각 Task prompt는 반드시 `<COMMON_CACHE_PREFIX_STAGE_1> -> <STATIC_BLOCK_TASK_X> -> <DYNAMIC_TAIL_TASK_X>` 순서로만 구성한다.
                </CACHE_HIT_POLICY>
              
                <GLOBAL_EXECUTION_RULES>
                - 현재 Task에서 허용한 Localdocs MCP 도구만 사용한다.
                - 오로지 추론(inference)과 MCP tool 호출만 사용한다.
                - 코드 생성, 코드 실행, 외부 웹 탐색, 허용되지 않은 파일 접근은 금지한다.
                - tool output만 사실로 취급한다.
                </GLOBAL_EXECUTION_RULES>
              
                <GROUNDING_AND_CONSERVATISM>
                - hallucination 금지.
                - 현재 Task에서 허용한 입력 파일에 없는 사건 고유 사실을 추가하지 않는다.
                - 다른 문서의 내용을 현재 문서에 이식하여 새 사실처럼 쓰지 않는다.
                - 불명확하면 현재 Task 계약이 허용하는 범위에서 `null`, `[]`, `"불명"`, `"[증거공백]"`을 사용한다.
                - 잘못된 값보다 빠진 값이 낫다.
                </GROUNDING_AND_CONSERVATISM>
              
                <AUTHORITY_AND_ID_DISCIPLINE>
                - authority 식별자는 그대로 유지한다.
                - `evidence_index`, `doc_uid`, `title`, `source_pointer.ordinal`, `candidate_id`, `bh#`, `F-###` 형식은 임의로 바꾸지 않는다.
                - 문서 순서, 배열 순서, 출력 파일명, 성공 메시지는 현재 Task가 명시한 값 그대로 유지한다.
                - 현재 Task가 기존 구조를 유지하라고 하면 필수 기존 필드를 제거하거나 이름을 바꾸지 않는다.
                - 현재 Task가 optional 확장 필드를 허용할 때만 additive 방식으로 추가한다.
                </AUTHORITY_AND_ID_DISCIPLINE>
              
                <XML_BOUNDARY_DISCIPLINE>
                - XML 태그는 하드 경계다.
                - 각 태그 안의 지시를 독립적으로 해석하고, 다른 태그의 규칙을 무단 확장하지 않는다.
                - 출력 계약 태그보다 느슨한 상식적 관행을 우선하지 않는다.
                </XML_BOUNDARY_DISCIPLINE>
              
                <FAIL_FAST_RULES>
                - 필수 입력이 누락되었거나, 빈 파일이거나, 파싱이 불가능하면 즉시 중단하고 출력 파일을 쓰지 않는다.
                - tool 오류가 발생하면 원인을 점검한 뒤 1회만 재시도한다.
                - 재시도 후에도 실패하면 해당 체크리스트 단계만 FAILED로 보고하고 종료한다.
                </FAIL_FAST_RULES>
              
                <BACKWARD_COMPATIBILITY_POLICY>
                - 현재 수정 대상이 아닌 Stage 1 다른 Task와의 호환을 해치지 않도록, 기존 필수 필드와 파일명은 유지한다.
                - schema 확장은 optional additive 방식으로만 수행한다.
                - 기존 필드가 위험하게 오염될 가능성이 있으면, 잘못된 요약값을 쓰지 말고 해당 필드를 생략하거나 `null`로 두는 쪽을 택한다.
                - multi-event 문서를 단일 snapshot으로 왜곡하여 downstream을 오염시키지 않는다.
                </BACKWARD_COMPATIBILITY_POLICY>
              </COMMON_CACHE_PREFIX_STAGE_1>
              
              <STATIC_BLOCK_TASK_B3>
                <TASK_META>
                  <TASK_NAME>Task_B3</TASK_NAME>
                  <ROLE>
                  You are an MCP-enabled LLM agent assisting plaintiff-side Korean civil/commercial litigation counsel.
                  </ROLE>
                  <MISSION>
                  `evidence_indexed.json`, `evidence_all.json`, `client_meeting.md`, `BO.json`, `actio_case_signals.json`을 사용하여
                  사해행위취소 및 가액배상 계산에 필요한 문서별 sparse support delta `evidence_actio_support.json`을 생성한다.
                  이 출력은 base catalog를 다시 쓰는 것이 아니라, `evidence_index` 기준으로 조인 가능한 support-only delta여야 한다.
                  기존 sparse delta 구조는 유지하되, 하나의 문서가 직접 뒷받침하는 복수 snapshot을 문서 안에서 소실하지 않도록 보강한다.
                  </MISSION>
                </TASK_META>
              
                <ALLOWED_IO_AND_FORBIDDEN_ACTIONS>
                  <IN>
                  - `evidence_indexed.json`
                  - `evidence_all.json`
                  - `client_meeting.md`
                  - `BO.json`
                  - `actio_case_signals.json`
                  </IN>
                  <OUT>
                  - `evidence_actio_support.json`
                  </OUT>
                  <ABSOLUTE_FORBIDDEN>
                  - 다른 파일 확인/읽기
                  - 중간 파일 생성
                  - `evidence_actio_support.json` 재읽기
                  - 현재 문서가 직접 뒷받침하지 않는 support를 다른 문서 내용으로 보충하기
                  - meeting의 서술만으로 현재 문서의 direct support를 가장하기
                  - 최종 보전채권 총액, 최종 수익자이익, 최종 회복한도 등 계산결론 만들기
                  </ABSOLUTE_FORBIDDEN>
                </ALLOWED_IO_AND_FORBIDDEN_ACTIONS>
              
                <EXECUTION_SEQUENCE>
                1. `actio_case_signals.json`과 `BO.json`을 기준으로 사건 수준 scope를 먼저 정한다.
                2. `evidence_indexed.json` 순서대로 문서를 훑되, scope 밖 문서는 원칙적으로 support 생성 대상에서 제외한다.
                3. 각 문서에 대해 현재 문서가 직접 뒷받침하는 sparse `actio_pauliana_support`만 추출한다.
                4. support가 있는 문서만 배열에 남긴다.
                5. `write_file(overwrite=true)`로 `evidence_actio_support.json`을 저장한다.
                6. `list_docs`로 파일 존재만 확인한다. 절대 읽지 않는다.
                7. 정확히 `"사해행위취소 support 인덱싱 완료"`만 출력하고 종료한다.
                </EXECUTION_SEQUENCE>
              
                <FAILURE_POLICY>
                - 필수 입력 누락, 빈 파일, 파싱 불가: 즉시 중단하고 채팅으로만 보고한다. 파일은 쓰지 않는다.
                - tool 오류: 원인 확인 후 1회만 재시도한다. 재실패 시 `FAILED: <step>`만 보고하고 종료한다.
                </FAILURE_POLICY>
              
                <SCOPE_PRIORITY>
                relevant document scope는 아래 우선순위로 정한다.
                1. `actio_case_signals.related_evidence_indexes`
                2. `actio_case_signals.target_property_candidates`
                3. `actio_case_signals.fraudulent_act_date_candidates`
                4. `actio_case_signals.preserved_claim_candidates`
                5. `BO.json`에서 관련 `Evidence[].evidence_index`
              
                규칙:
                - 위 기준과 실질적으로 연결되지 않는 문서는 support 생성 대상에서 제외할 수 있다.
                - 다만 같은 자산 cluster, 같은 피보전채권 cluster, 같은 수익자/부담 구조와 직접 연결되는 문서는 포함할 수 있다.
                - `evidence_indexed.json`의 optional field(`property_cluster_id`, `doc_semantic_flags`, `legal_calculation_objects`, `valuation_object`, `contract_components`)는 scope 보조에 사용할 수 있다.
                </SCOPE_PRIORITY>
              
                <CORE_PRINCIPLES>
                - support는 현재 문서가 직접 뒷받침하는 범위에서만 만든다.
                - 하나의 문서가 직접 보여주는 복수 snapshot은 가능한 한 모두 보존한다.
                - 특히 같은 문서 안에 복수의 대여/차용 snapshot, 복수의 부담 row, 복수의 가치 row가 있으면 첫 항목만 남기고 나머지를 버리지 않는다.
                - `proof_doc`는 반드시 현재 문서의 `evidence_index`만 사용한다.
                - 문서 안에서 직접 분해할 수 없는 불명확한 support는 과감히 생략한다.
                </CORE_PRINCIPLES>
              
                <DIRECT_SOURCE_DISCIPLINE>
                - 1차 소스는 현재 처리 중인 `evidence_all.json`의 해당 문서다.
                - 2차 소스는 `evidence_indexed.json` authority metadata다.
                - 3차 소스는 `client_meeting.md`, `BO.json`, `actio_case_signals.json`이며, 오직 scope와 의미 해석 보조로만 사용한다.
                - meeting, BO, signals만으로 현재 문서 support field를 창작하지 않는다.
                </DIRECT_SOURCE_DISCIPLINE>
              
                <SUPPORT_GENERATION_GATE>
                아래 중 하나라도 충족하면 현재 문서 support 생성을 검토한다.
                - 사해행위 목적물의 처분, 이전, 등기, 거래가액, 시가를 직접 보여주는 문서
                - 가액배상 공제문제에 연결되는 선순위 담보권, 존속 담보권, 말소 담보권, 임차권, 전세권, 가압류를 직접 보여주는 문서
                - 원고별 피보전채권의 원금, 이율, 만기, 연체, 잔액, 대위변제, 배당을 직접 보여주는 문서
                - 수익자의 사전채권, 인수채무, 변제한 부담, 실질 취득이익을 직접 보여주는 문서
                - `Task_C`가 포착한 관련 자산/관련 BO/관련 시점과 결합될 때 현재 문서가 사해행위취소 계산의 직접 증거가 되는 문서
                </SUPPORT_GENERATION_GATE>
              
                <ROLE_TAG_RULES>
                `support_role_tags` 허용값:
                - `"사해행위목적물"`
                - `"선순위담보"`
                - `"존속담보"`
                - `"임차권"`
                - `"가압류"`
                - `"원고채권"`
                - `"수익자이익"`
                - `"법리메타"`
                </ROLE_TAG_RULES>
              
                <FRAUDULENT_ACT_DATE_RULES>
                - `fraudulent_act_date`는 현재 문서가 직접 목적물의 처분일/이전일/이전원인일을 보여주는 경우에만 채운다.
                - 단순 대여/보증/통지 문서에는 절대 채우지 않는다.
                - 같은 claim packet 안에 있다는 이유만으로 다른 문서의 처분일을 올리지 않는다.
                </FRAUDULENT_ACT_DATE_RULES>
              
                <MULTI_SNAPSHOT_RULES>
                  <PLAINTIFF_CLAIM_SNAPSHOT_RULE>
                  - 하나의 문서가 복수의 차용증, 복수의 대여분, 복수의 보증분, 복수의 대위변제 snapshot을 직접 보여주면 `plaintiff_claim_snapshots`에 모두 남긴다.
                  - snapshot은 문서 안에서 구별 가능한 단위별로 분리한다.
                  - 가능하면 각 snapshot에 아래 optional field를 함께 남긴다.
                    - `claim_arising_date_candidate`
                    - `creditor_candidate`
                    - `debtor_candidate`
                  - 이 optional field들은 후속 BO 매핑 보조용이며, 직접 읽히는 경우에만 사용한다.
                  </PLAINTIFF_CLAIM_SNAPSHOT_RULE>
              
                  <ENCUMBRANCE_MULTIROW_RULE>
                  - 등기부나 표 형식 문서에서 복수 부담 row가 의미 있게 존재하면 `encumbrances_at_fraudulent_act` 또는 `encumbrances_at_close_of_arguments`에 모두 남긴다.
                  - 동일 항목을 억지로 합산하거나 단일 row로 축약하지 않는다.
                  </ENCUMBRANCE_MULTIROW_RULE>
              
                  <VALUATION_MULTIROW_RULE>
                  - 가치표/시가표/차임표는 가장 직접적인 candidate만 남기되, 문서가 복수 기준일을 직접 보이면 그 중 사건 scope와 직접 연결되는 row를 선택한다.
                  - 같은 문서에서 act 시점과 현재 시점 가치가 모두 직접 보이면, 가능한 경우 각각 `market_value_at_act`와 `property_value_at_close_of_arguments_support` 취지로 구분한다.
                  </VALUATION_MULTIROW_RULE>
                </MULTI_SNAPSHOT_RULES>
              
                <FIELD_RULES>
                  <PROPERTY_VALUE_CLOSE_RULE>
                  - `property_value_at_close_of_arguments_support`는 처분 목적물의 현재 가치 또는 대체 시점 가치를 직접 보여주는 문서에만 사용한다.
                  - `candidate_amount`, `candidate_date`, `basis_type`, `reason_text`, `confidence`, `proof_doc`만 사용한다.
                  </PROPERTY_VALUE_CLOSE_RULE>
              
                  <ENCUMBRANCE_RULE>
                  - `encumbrances_at_fraudulent_act`와 `encumbrances_at_close_of_arguments`는 같은 목적물 cluster와 직접 연결되는 부담만 남긴다.
                  - `kind`, `holder`, `rank`, `registered_max_amount`, `actual_secured_debt_at_act`, `actual_outstanding_at_close`, `released_date`, `released_by_beneficiary`는 현재 문서가 직접 보여줄 때만 채운다.
                  - 최종 공제 결론은 쓰지 않고 `deductible_in_value_compensation`과 `deductibility_reason` 정도의 candidate 수준만 허용한다.
                  </ENCUMBRANCE_RULE>
              
                  <LEASE_AND_ATTACHMENT_RULE>
                  - `lease_deposit_deductibility_support`는 임차권 구조와 직접 연결되는 문서에만 채운다.
                  - `non_deductible_attachment_claims`는 가압류/압류의 비공제 candidate를 직접 보여주는 문서에만 채운다.
                  </LEASE_AND_ATTACHMENT_RULE>
              
                  <BENEFICIARY_GAIN_RULE>
                  - `beneficiary_gain_support`는 처분 상대방의 수익 귀속, 사전채권, 인수채무, 부담 해소를 현재 문서가 직접 보여줄 때만 사용한다.
                  - 계산 결과가 아니라 candidate 수준 문구만 허용한다.
                  </BENEFICIARY_GAIN_RULE>
              
                  <PLAINTIFF_CLAIM_RULE>
                  - `plaintiff_claim_snapshots.claim_type` 허용값은 `"loan"|"guarantee"|"reimbursement"`다.
                  - 원금, 담보부분/무담보부분, 금리, 기준시점 잔액은 현재 문서가 직접 보여줄 때만 채운다.
                  - optional `claim_arising_date_candidate`, `creditor_candidate`, `debtor_candidate`는 후속 mapping 보조용이며, 직접 기재가 있을 때만 채운다.
                  </PLAINTIFF_CLAIM_RULE>
              
                  <LEGAL_META_RULE>
                  - `legal_meta_flags`는 결론이 아니라 candidate flag다.
                  - 같은 문서에 실질 support field가 하나도 없으면 메타 플래그만 단독으로 남기지 않는다.
                  </LEGAL_META_RULE>
                </FIELD_RULES>
              
                <OUTPUT_SCHEMA>
                최종 파일은 배열(Array)이다.
              
                [
                  {
                    "evidence_index": "E-014",
                    "actio_pauliana_support": {
                      "support_role_tags": ["사해행위목적물"],
                      "fraudulent_act_date": "2023-03-17",
                      "property_value_at_close_of_arguments_support": {
                        "candidate_amount": "string",
                        "candidate_date": "string",
                        "basis_type": "사실심변론종결직접|현재시점대체|감정기준일|거래시점동일|불명",
                        "reason_text": "string",
                        "confidence": "high|medium|low|unknown",
                        "proof_doc": "E-014"
                      },
                      "encumbrances_at_fraudulent_act": [
                        {
                          "kind": "근저당|저당|가압류|전세권|임차보증금반환채권",
                          "holder": "string",
                          "rank": 1,
                          "registered_max_amount": "string",
                          "actual_secured_debt_at_act": "string",
                          "supported_date": "string",
                          "deductible_in_value_compensation": true,
                          "deductibility_reason": "string",
                          "proof_doc": "E-014",
                          "proof_strength": "direct|indirect|meeting_only|unknown"
                        }
                      ],
                      "encumbrances_at_close_of_arguments": [
                        {
                          "kind": "근저당|저당|가압류|전세권|임차보증금반환채권",
                          "holder": "string",
                          "rank": 1,
                          "actual_outstanding_at_close": "string",
                          "released_date": "string",
                          "released_by_beneficiary": true,
                          "proof_doc": "E-014",
                          "proof_strength": "direct|indirect|meeting_only|unknown"
                        }
                      ],
                      "lease_deposit_deductibility_support": {
                        "tenant_name": "string",
                        "lease_deposit_amount": "string",
                        "has_possession": true,
                        "has_resident_registration": true,
                        "has_fixed_date": true,
                        "senior_security_exists": true,
                        "deductible_candidate": true,
                        "deductibility_reason": "string",
                        "proof_doc": "E-014",
                        "proof_strength": "direct|indirect|meeting_only|unknown"
                      },
                      "non_deductible_attachment_claims": [
                        {
                          "holder": "string",
                          "kind": "가압류|압류",
                          "claim_amount": "string",
                          "attachment_non_deductible_flag": true,
                          "reason": "string",
                          "proof_doc": "E-014",
                          "proof_strength": "direct|indirect|meeting_only|unknown"
                        }
                      ],
                      "beneficiary_gain_support": {
                        "beneficiary_name": "string",
                        "nominal_transfer_value": "string",
                        "beneficiary_preexisting_claim_amount": "string",
                        "assumed_debt_amount": "string",
                        "released_encumbrance_amount": "string",
                        "beneficiary_gain_estimate_candidate": "string",
                        "estimation_basis": "string",
                        "proof_doc": "E-014",
                        "confidence": "high|medium|low|unknown"
                      },
                      "plaintiff_claim_snapshots": [
                        {
                          "plaintiff_name": "string",
                          "claim_type": "loan|guarantee|reimbursement",
                          "principal_existing_at_fraudulent_act": "string",
                          "secured_portion_at_fraudulent_act": "string",
                          "unsecured_portion_at_fraudulent_act": "string",
                          "contractual_interest_rate": "string",
                          "default_interest_rate": "string",
                          "interest_start_date": "string",
                          "amount_as_of_close_of_arguments": "string",
                          "proof_status": "direct|indirect|meeting_only|unknown",
                          "proof_doc": "E-014",
              
                          "claim_arising_date_candidate": "string",
                          "creditor_candidate": "string",
                          "debtor_candidate": "string"
                        }
                      ],
                      "legal_meta_flags": {
                        "is_actio_pauliana_relevant_candidate": true,
                        "restoration_mode_candidate": "원물반환|말소등기|가액배상",
                        "is_value_compensation_exception_triggered_candidate": true,
                        "lease_deposit_deductible_candidate": true,
                        "attachment_claim_deductible_candidate": false,
                        "remaining_joint_collateral_value_estimate_candidate": "string",
                        "beneficiary_gain_estimate_candidate": "string",
                        "confidence_score": "high|medium|low|unknown"
                      }
                    }
                  }
                ]
              
                추가 제약:
                - support가 없는 문서는 출력하지 않는다.
                - 최상위 키는 `evidence_index`, `actio_pauliana_support`만 허용한다.
                - `claim_arising_date_candidate`, `creditor_candidate`, `debtor_candidate`는 `plaintiff_claim_snapshots` 내부 optional additive field로만 허용한다.
                - 그 외 임의 추가 필드 금지.
                </OUTPUT_SCHEMA>
              
                <PRUNING_AND_VALIDATION>
                - `actio_pauliana_support`가 비면 해당 문서는 출력하지 않는다.
                - 최종 출력에서 `null`, 빈 배열 `[]`, 빈 객체 `{}`는 제거한다.
                - 같은 문서가 직접 뒷받침하는 복수 snapshot이 있는데 first item만 남기고 다른 항목을 잃지 않았는지 점검한다.
                - `proof_doc`가 모두 현재 `evidence_index`와 일치하는지 점검한다.
                - `fraudulent_act_date`가 비처분 문서에 잘못 올라가지 않았는지 점검한다.
                </PRUNING_AND_VALIDATION>
              </STATIC_BLOCK_TASK_B3>
              
              <DYNAMIC_TAIL_TASK_B3>
                <CHECKLIST>
                [ ] 1) Preflight: `list_docs` 사용해서 `evidence_indexed.json`, `evidence_all.json`, `client_meeting.md`, `BO.json`, `actio_case_signals.json`만 확인하고, `read_docs` 사용해서 해당 파일만 읽기
                [ ] 2) `write_file` 사용해서 `evidence_actio_support.json` 생성
                [ ] 3) `list_docs` 사용해서 `evidence_actio_support.json` 파일만 존재 확인(절대 읽기 금지)
                [ ] 4) `"사해행위취소 support 인덱싱 완료"` 출력하고 작업을 끝낸다(terminate)
                </CHECKLIST>
              
                <RUNTIME_FILES>
                  <INPUT_FILES>
                  - `evidence_indexed.json`
                  - `evidence_all.json`
                  - `client_meeting.md`
                  - `BO.json`
                  - `actio_case_signals.json`
                  </INPUT_FILES>
                  <OUTPUT_FILE>
                  - `evidence_actio_support.json`
                  </OUTPUT_FILE>
                </RUNTIME_FILES>
              
                <FINAL_REMINDERS>
                - `evidence_actio_support.json`은 절대 재읽지 않는다.
                - 성공 시 마지막 채팅 출력은 정확히 `"사해행위취소 support 인덱싱 완료"` 한 줄만 사용한다.
                </FINAL_REMINDERS>
              </DYNAMIC_TAIL_TASK_B3>                

        - task_name: Task_D1
          llm_provider: google
          llm_model: 'gemini-3.1-flash-lite-preview'
          llm_reasoning: high
          llm_verbosity: medium
          cache_control:
            mode: auto
            ttl: 10m
          use_tools:
          - localdocs
          prompts:
          - role: user
            content: |-
              <ABSOLUTE_SYSTEM_RULES>
              - You MUST execute every single instruction provided below without any omission.
              - DO NOT arbitrarily reduce, summarize, or skip any steps, reasoning processes, or outputs.
              - DO NOT use placeholders like "..." or "rest of the code/text". Provide the exhaustive and complete output.
              - Adhere strictly to these rules before processing the prompt.
              </ABSOLUTE_SYSTEM_RULES>

              <COMMON_CACHE_PREFIX_STAGE_1>
                <STAGE_CONTEXT>
                당신은 대한민국 민사소송 원고대리 사건을 구조화하는 Stage 1 전용 정밀 LLM이다.
                이 프롬프트는 LLM의 안정적 추론, 구조 보존, 식별자 보존, 후속 단계 조인 안정성을 최우선으로 설계되었다.
                </STAGE_CONTEXT>
              
                <CACHE_HIT_POLICY>
                - 이 블록은 Stage 1의 Task_A, Task_B1, Task_B2, Task_B3, Task_C, Task_D1, Task_D2에서 byte-level로 최대한 동일하게 유지한다.
                - 이 블록 앞에는 어떤 문장도 두지 않는다.
                - 이 블록의 문구, 태그명, 순서, 공백, 줄바꿈, 구두점은 가급적 수정하지 않는다.
                - 각 Task prompt는 반드시 `<COMMON_CACHE_PREFIX_STAGE_1> -> <STATIC_BLOCK_TASK_X> -> <DYNAMIC_TAIL_TASK_X>` 순서로만 구성한다.
                </CACHE_HIT_POLICY>
              
                <GLOBAL_EXECUTION_RULES>
                - 현재 Task에서 허용한 Localdocs MCP 도구만 사용한다.
                - 오로지 추론(inference)과 MCP tool 호출만 사용한다.
                - 코드 생성, 코드 실행, 외부 웹 탐색, 허용되지 않은 파일 접근은 금지한다.
                - tool output만 사실로 취급한다.
                </GLOBAL_EXECUTION_RULES>
              
                <GROUNDING_AND_CONSERVATISM>
                - hallucination 금지.
                - 현재 Task에서 허용한 입력 파일에 없는 사건 고유 사실을 추가하지 않는다.
                - 다른 문서의 내용을 현재 문서에 이식하여 새 사실처럼 쓰지 않는다.
                - 불명확하면 현재 Task 계약이 허용하는 범위에서 `null`, `[]`, `"불명"`, `"[증거공백]"`을 사용한다.
                - 잘못된 값보다 빠진 값이 낫다.
                </GROUNDING_AND_CONSERVATISM>
              
                <AUTHORITY_AND_ID_DISCIPLINE>
                - authority 식별자는 그대로 유지한다.
                - `evidence_index`, `doc_uid`, `title`, `source_pointer.ordinal`, `candidate_id`, `bh#`, `F-###` 형식은 임의로 바꾸지 않는다.
                - 문서 순서, 배열 순서, 출력 파일명, 성공 메시지는 현재 Task가 명시한 값 그대로 유지한다.
                - 현재 Task가 기존 구조를 유지하라고 하면 필수 기존 필드를 제거하거나 이름을 바꾸지 않는다.
                - 현재 Task가 optional 확장 필드를 허용할 때만 additive 방식으로 추가한다.
                </AUTHORITY_AND_ID_DISCIPLINE>
              
                <XML_BOUNDARY_DISCIPLINE>
                - XML 태그는 하드 경계다.
                - 각 태그 안의 지시를 독립적으로 해석하고, 다른 태그의 규칙을 무단 확장하지 않는다.
                - 출력 계약 태그보다 느슨한 상식적 관행을 우선하지 않는다.
                </XML_BOUNDARY_DISCIPLINE>
              
                <FAIL_FAST_RULES>
                - 필수 입력이 누락되었거나, 빈 파일이거나, 파싱이 불가능하면 즉시 중단하고 출력 파일을 쓰지 않는다.
                - tool 오류가 발생하면 원인을 점검한 뒤 1회만 재시도한다.
                - 재시도 후에도 실패하면 해당 체크리스트 단계만 FAILED로 보고하고 종료한다.
                </FAIL_FAST_RULES>
              
                <BACKWARD_COMPATIBILITY_POLICY>
                - 현재 수정 대상이 아닌 Stage 1 다른 Task와의 호환을 해치지 않도록, 기존 필수 필드와 파일명은 유지한다.
                - schema 확장은 optional additive 방식으로만 수행한다.
                - 기존 필드가 위험하게 오염될 가능성이 있으면, 잘못된 요약값을 쓰지 말고 해당 필드를 생략하거나 `null`로 두는 쪽을 택한다.
                - multi-event 문서를 단일 snapshot으로 왜곡하여 downstream을 오염시키지 않는다.
                </BACKWARD_COMPATIBILITY_POLICY>
              </COMMON_CACHE_PREFIX_STAGE_1>
              
              <STATIC_BLOCK_TASK_D1>
                <TASK_META>
                  <TASK_NAME>Task_D1</TASK_NAME>
                  <ROLE>
                  You are an MCP-enabled LLM agent assisting plaintiff-side Korean civil/commercial litigation counsel.
                  </ROLE>
                  <MISSION>
                  `BO.json`과 `evidence_indexed.json`을 읽고, 각 BO에 대응하는 base fact ledger 항목 1개를 생성하여 `Fact_Ledger_base.json`을 만든다.
                  이 단계의 핵심 목적은 `1 BO = 1 Fact`를 유지하면서, multi-event 문서의 later snapshot이 현재 BO를 오염시키지 않도록 slot-safe 병합을 수행하는 것이다.
                  기존 base ledger schema는 유지하되, linked evidence의 legacy singular `legal_calculation_object`를 무조건 주입하지 말고, 가능한 경우 event-aligned slot만 선택적으로 병합한다.
                  </MISSION>
                </TASK_META>
              
                <ALLOWED_IO_AND_FORBIDDEN_ACTIONS>
                  <IN>
                  - `BO.json`
                  - `evidence_indexed.json`
                  </IN>
                  <OUT>
                  - `Fact_Ledger_base.json`
                  </OUT>
                  <ABSOLUTE_FORBIDDEN>
                  - 다른 파일 확인/읽기
                  - 중간 파일 생성
                  - `Fact_Ledger_base.json` 재읽기
                  - `actio_pauliana_support`를 base ledger에 포함하기
                  - linked evidence 밖의 다른 증거를 끌어와 계산객체를 병합하기
                  - BO 본문이나 `key_*`만으로 새 `legal_calculation_object`를 창작하기
                  - multi-event 문서의 later snapshot을 현재 BO에 기계적으로 주입하기
                  </ABSOLUTE_FORBIDDEN>
                </ALLOWED_IO_AND_FORBIDDEN_ACTIONS>
              
                <EXECUTION_SEQUENCE>
                1. `list_docs`로 `BO.json`, `evidence_indexed.json` 존재만 확인한다.
                2. `read_docs`로 위 두 파일만 읽는다.
                3. `BO.json` 배열 순서대로 `1 BO = 1 Fact` 원칙에 따라 메모리에서 `Fact_Ledger_base.json` 배열을 생성한다.
                4. 각 BO의 linked evidence에 대해 authority drift를 검사한다.
                5. 각 BO에 대해 safe linked slot이 있을 때만 선택적으로 `legal_calculation_object`를 병합한다.
                6. `write_file(overwrite=true)`로 `Fact_Ledger_base.json`을 저장한다.
                7. `list_docs`로 파일 존재만 확인한다. 절대 읽지 않는다.
                8. 정확히 `"Fact Ledger base 생성 완료"`만 출력하고 종료한다.
                </EXECUTION_SEQUENCE>
              
                <FAILURE_POLICY>
                - 필수 입력 누락, 빈 파일, 파싱 불가: 즉시 중단하고 채팅으로만 보고한다. 파일은 쓰지 않는다.
                - tool 오류: 원인 확인 후 1회만 재시도한다. 재실패 시 `FAILED: <step>`만 보고하고 종료한다.
                - evidence authority drift가 1건이라도 발견되면 즉시 중단한다.
                </FAILURE_POLICY>
              
                <INPUT_CONTRACT>
                  <BO_JSON_RULES>
                  - `BO.json`은 배열이다.
                  - 각 BO는 `id`, `Performer`, `PerformerType`, `Action`, `ActionType`, `Subject`, `Reason`, `PriorAct`, `BehaviorTime`, `TimeText`, `TimePrecision`, `StatementType`, `Perspective`, `EvidenceTitles`, `Evidence[]`를 가진다.
                  - 선택적으로 `Object`, `Method`, `Location`, `Outcome`, `Legal_Keywords`, `JuristicAct`를 가질 수 있다.
                  </BO_JSON_RULES>
              
                  <EVIDENCE_INDEXED_RULES>
                  - `evidence_indexed.json`은 authority catalog다.
                  - 기존 필수 필드(`evidence_index`, `title`, `doc_type`, `source_pointer`, `key_*`)를 사용한다.
                  - 아래 optional field가 있으면 읽을 수 있다.
                    - `property_cluster_id`
                    - `doc_semantic_flags`
                    - `multi_event_registry`
                    - `legal_calculation_object` (legacy singular)
                    - `legal_calculation_objects` (slot array)
                    - `contract_components`
                    - `valuation_object`
                  - `actio_pauliana_support`가 있더라도 이 작업에서는 완전히 무시한다.
                  </EVIDENCE_INDEXED_RULES>
                </INPUT_CONTRACT>
              
                <CORE_NON_NEGOTIABLES>
                - `1 BO = 1 Fact`를 엄수한다.
                - `BO.json` 배열 순서를 최종 출력 순서로 유지한다.
                - top-level Fact 필드는 BO를 1차 소스로 사용한다.
                - `legal_calculation_object` 내부 필드는 linked evidence의 계산객체에서만 가져온다.
                - linked evidence가 없거나, safe slot selection이 불가능하면 `legal_calculation_object`를 아예 생성하지 않는다.
                - 잘못된 병합보다 생략이 낫다.
                </CORE_NON_NEGOTIABLES>
              
                <AUTHORITY_DRIFT_RULES>
                - `evidence_indexed.json`을 `evidence_index` 기준 해시맵으로 만든다.
                - 각 BO의 `Evidence[]`를 순회하며 `evidence_index`가 일치하는 authority evidence만 linked evidence로 채택한다.
                - `evidence_index`가 `null`이거나 매칭 실패면 그 evidence item은 스킵한다.
                - 단, `source_title`과 authority `title`이 모두 존재할 때,
                  - 앞뒤 공백 제거
                  - 괄호/전각공백 정규화
                  - 연속공백 축약
                  후에도 제목이 불일치하면 evidence authority drift로 보고 즉시 중단한다.
                </AUTHORITY_DRIFT_RULES>
              
                <TOP_LEVEL_FACT_MAPPING_RULES>
                  <FACT_ID_RULE>
                  - `fact_id`는 `"F-001"`, `"F-002"` 식의 3자리 0패딩을 사용한다.
                  - `source_bo_id`는 `BO.id`를 그대로 복사한다.
                  </FACT_ID_RULE>
              
                  <TYPE_RULE>
                  - `type`은 `BO.ActionType`을 그대로 사용한다.
                  </TYPE_RULE>
              
                  <DATE_RULE>
                  - `date` 1순위는 `BO.BehaviorTime`이다.
                  - `BO.BehaviorTime`이 없을 때만 selected slot의 직접 대응 필드에서 보조한다.
                  - 보조 우선순위:
                    1. 처분/이전/증여/대물변제/경매매각 BO -> `transaction_date`
                    2. 등기/공시/말소 BO -> `registration_date`
                    3. 대여/보증/구상권발생 BO -> `claim_arising_date`
                    4. 변제/대위변제/배당 BO -> `claim_performance_date`
                    5. 만기/연체/기한의이익상실 BO -> `claim_default_or_acceleration_date`
                    6. 그 외 -> `claim_instrument_date`
                  - 그래도 없으면 `null`.
                  </DATE_RULE>
              
                  <PARTY_RULE>
                  - `parties`는 아래 순서로 수집하고 exact-match 중복 제거한다.
                    1. `BO.Performer`
                    2. `BO.Subject`가 사람 또는 법인 이름일 때
                    3. `BO.Action`에 직접 나타나는 상대방 이름
                    4. selected slot에서 현재 BO와 직접 관련된 당사자
                      - `claim_creditor`
                      - `claim_debtor`
                      - `claim_guarantor`
                      - `claim_security_provider`
                  - 주소, 부동산 표기, 금액 문자열, 순수 채무명칭은 `parties`에 넣지 않는다.
                  - 최대 5개까지만 유지한다.
                  </PARTY_RULE>
              
                  <OBJECT_RULE>
                  - `object_spec`는 아래 우선순위로 짧은 명사구 1개를 만든다.
                    1. `BO.Object`
                    2. `BO.Subject`가 직접 객체를 가리키는 경우 그 값
                    3. `BO.Action`에서 현재 행위의 목적물 부분을 짧게 추출
                    4. selected slot이 더 직접적이면 slot의 목적물/자산 표현
                  - 불명확하면 `null`.
                  </OBJECT_RULE>
              
                  <AMOUNT_RULE>
                  - `amount`는 해당 Fact의 대표 금액 1개다.
                  - 1순위: `BO.Action` 또는 `BO.Object`에 현재 행위와 직접 연결된 금액
                  - 2순위: selected slot의 현재 BO와 직접 대응하는 금액
                    - 처분/매매/증여/대물변제/영업양도 -> `sale_price`
                    - 대여/차용 -> `claim_principal_amount_at_act`
                    - 보증한도 -> `claim_guarantee_limit_amount`
                    - 담보최고액 -> `claim_secured_cap_amount`
                    - 변제/대위변제/배당 -> `claim_actual_performance_amount`
                    - 잔존채권 파악 -> `claim_outstanding_amount_at_close`
                  - `sale_price`를 기계적으로 복사하지 않는다.
                  - 불명확하면 `null`.
                  </AMOUNT_RULE>
              
                  <ACTION_RULE>
                  - `action`은 `BO.Action`을 바탕으로 1문장으로 정리하되, 새 사실 추가 없이 군더더기만 줄인다.
                  </ACTION_RULE>
              
                  <EVIDENCE_REFS_RULE>
                  - 매칭된 authority evidence에 대해 `E-001 (title)` 형식으로 기록한다.
                  - 매칭된 evidence가 없으면 `["증거공백"]`.
                  - exact-match 중복 제거한다.
                  </EVIDENCE_REFS_RULE>
              
                  <CREDIBILITY_RULE>
                  - `high`:
                    - linked evidence 중 `content_relevance=="직접"`가 1개 이상이고,
                    - 그 evidence의 `doc_type`이 `공문서`, `처분문서`, `거래기록` 중 하나이거나,
                    - 복수 증거가 서로 보강한다.
                  - `medium`:
                    - linked evidence는 있으나 직접성, 문서성, 보강 정도가 혼재한다.
                  - `low`:
                    - linked evidence가 없거나,
                    - `간접`, `불명`, `반대` 위주이거나,
                    - `["증거공백"]` 상태다.
                  </CREDIBILITY_RULE>
                </TOP_LEVEL_FACT_MAPPING_RULES>
              
                <SAFE_SLOT_SELECTION_RULES>
                  <LINKED_EVIDENCE_ORDER>
                  같은 BO의 linked evidence는 아래 기준으로 정렬한다.
                  1. `BO.Evidence[].content_relevance`: `"직접"` > `"간접"` > `"불명"` > `"반대"`
                  2. authority `doc_type`: `"처분문서"` > `"공문서"` > `"거래기록"` > `"판결/결정"` > `"통신기록"` > `"기타"`
                  3. `evidence_index` 오름차순
                  </LINKED_EVIDENCE_ORDER>
              
                  <SLOT_SOURCE_PRIORITY>
                  - 1순위: authority evidence의 `legal_calculation_objects[]`
                  - 2순위: authority evidence의 legacy singular `legal_calculation_object`
                  - 단, authority evidence가 `multi_event_registry==true`이거나 `doc_semantic_flags`에 `multi_event_doc`가 있으면 legacy singular는 원칙적으로 unsafe로 본다.
                  - multi-event 문서에서 slot array가 없고 legacy singular만 있는 경우, 현재 BO와의 안전한 1:1 대응이 명백하지 않으면 legacy singular 병합을 금지한다.
                  </SLOT_SOURCE_PRIORITY>
              
                  <SEMANTIC_CLASS_RULE>
                  현재 BO의 semantic class를 먼저 정한다.
                  - `ownership_transfer_class`: 소유권이전, 매매, 증여, 대물변제, 경매매각, 소유권보존, 이전등기
                  - `encumbrance_setting_class`: 근저당/저당/전세권/담보설정
                  - `encumbrance_cancellation_class`: 근저당권설정등기말소, 담보말소, 가압류말소
                  - `loan_claim_class`: 대여, 소비대차, 차용
                  - `performance_class`: 변제, 대위변제, 배당
                  - `business_transfer_class`: 영업양도
                  - `lease_class`: 임대차
                  - `status_or_other_class`: 그 외
                  </SEMANTIC_CLASS_RULE>
              
                  <SLOT_COMPATIBILITY_RULE>
                  slot 또는 legacy object는 현재 BO semantic class와 compatible할 때만 후보가 된다.
                  - `ownership_transfer_class` ↔ `ownership_transfer|sale|gift|dation|auction_sale`
                  - `encumbrance_setting_class` ↔ `mortgage_setting|other` 중 담보설정 직접 단서가 있는 경우
                  - `encumbrance_cancellation_class` ↔ `mortgage_cancellation|other` 중 말소 직접 단서가 있는 경우
                  - `loan_claim_class` ↔ `loan|other` 중 차용 직접 단서가 있는 경우
                  - `performance_class` ↔ `other` 중 변제/배당 직접 단서가 있는 경우
                  - `business_transfer_class` ↔ `business_transfer`
                  - `lease_class` ↔ `lease`
                  - compatible 판단이 불명확하면 후보에서 제외한다.
                  </SLOT_COMPATIBILITY_RULE>
              
                  <DATE_OBJECT_ALIGNMENT_RULE>
                  compatible 후보들 중에서도 아래 alignment가 하나 이상 있어야 selected slot 후보로 인정한다.
                  - slot date와 `BO.BehaviorTime`이 일치하거나 고도의 근접성
                  - slot party set과 `BO.Performer`/`BO.Subject`가 직접 부합
                  - slot asset/property/cluster가 `BO.Object` 또는 `BO.Action`의 목적물과 직접 부합
                  - contract component/source locator가 현재 BO와 직접 대응
                  - 위 alignment가 모두 약하면 selected slot으로 채택하지 않는다.
                  </DATE_OBJECT_ALIGNMENT_RULE>
              
                  <NO_SAFE_SLOT_RULE>
                  - linked evidence가 모두 multi-event 문서인데 safe slot을 특정할 수 없으면 `legal_calculation_object` 자체를 생략한다.
                  - 이 경우 top-level Fact는 BO만으로 생성한다.
                  - later snapshot 오염을 막기 위해, 애매한 경우 생략을 우선한다.
                  </NO_SAFE_SLOT_RULE>
                </SAFE_SLOT_SELECTION_RULES>
              
                <LEGAL_CALC_MERGE_RULES>
                  <GENERATION_GATE>
                  아래를 모두 충족할 때만 `legal_calculation_object`를 생성한다.
                  1. selected slot 또는 safe legacy object가 1개 이상 있다.
                  2. 현재 BO가 부동산 처분/이전/담보/차용/보증/변제/배당/영업양도 등 계산객체와 실질 관련이 있다.
                  3. 병합 결과가 빈 객체가 아니다.
                  </GENERATION_GATE>
              
                  <MERGE_PRINCIPLE>
                  - selected slot들에서만 값을 채운다.
                  - 스칼라는 first-non-null 원칙을 쓴다.
                  - 배열은 exact-match 중복 제거 후 최초 순서를 유지한다.
                  - 계산, 합산, 차감 금지.
                  - `key_facts`, `key_dates`, `key_amounts`, `key_parties`만으로 새 필드를 만들지 않는다.
                  </MERGE_PRINCIPLE>
              
                  <FIELD_GROUP_PRIORITY>
                  - 일반 부동산 거래 필드:
                    `asset_id`, `property_label_for_schedule`, `transaction_type`, `transaction_date`
                  - 등기 전용 필드:
                    `registration_date`, `registry_office`, `registry_receipt_no`, `registry_recorded_transfer_date`
                  - 가치/가격 필드:
                    `market_value_at_act`, `market_value_at_close`, `sale_price`
                  - 대가 구성 배열:
                    `consideration_breakdown`
                  - 채권 관계 필드:
                    `claim_id`, `claim_label_for_schedule`, `claim_event_type`, `claim_creditor`, `claim_debtor`, `claim_guarantor`, `claim_security_provider`
                  - 채권 성질/상태/구성 배열:
                    `claim_nature_tags`, `claim_component_breakdown`, `claim_status_tags`
                  - 채권 날짜 필드:
                    `claim_arising_date`, `claim_maturity_date`, `claim_default_or_acceleration_date`, `claim_performance_date`, `claim_instrument_date`
                  - 채권 문서 식별 필드:
                    `claim_instrument_identifier`, `claim_instrument_issuer`
                  - 채권 금액 필드:
                    `claim_principal_amount_at_act`, `claim_total_amount_at_act`, `claim_outstanding_amount_at_close`, `claim_actual_performance_amount`, `claim_guarantee_limit_amount`, `claim_secured_cap_amount`
                  - 금리 필드:
                    `claim_interest_rate`, `claim_default_rate`
                  </FIELD_GROUP_PRIORITY>
              
                  <EMPTY_OBJECT_RULE>
                  - 병합 후 스칼라가 전부 `null`이고 배열이 전부 비어 있으면 `legal_calculation_object`를 생성하지 않는다.
                  </EMPTY_OBJECT_RULE>
                </LEGAL_CALC_MERGE_RULES>
              
                <OUTPUT_SCHEMA>
                `Fact_Ledger_base.json`은 배열(Array)이며, 각 원소는 아래 필드만 가진다.
              
                {
                  "fact_id": "F-001",
                  "source_bo_id": "bh1",
                  "type": "string|null",
                  "date": "string|null",
                  "parties": [],
                  "object_spec": "string|null",
                  "amount": "string|null",
                  "action": "string|null",
                  "evidence_refs": [],
                  "credibility": "high|medium|low",
              
                  "legal_calculation_object": {
                    "asset_id": null,
                    "property_label_for_schedule": null,
                    "transaction_type": "매매|증여|대물변제|null",
                    "transaction_date": null,
                    "registration_date": null,
                    "registry_office": null,
                    "registry_receipt_no": null,
                    "registry_recorded_transfer_date": null,
                    "market_value_at_act": null,
                    "market_value_at_close": null,
                    "sale_price": null,
                    "consideration_breakdown": [],
              
                    "claim_id": null,
                    "claim_label_for_schedule": null,
                    "claim_event_type": "대여|연대보증|신용보증|보증채무|대위변제|구상권발생|변제|배당|채권양도|채무인수|상계|면제|경개|담보제공|null",
                    "claim_nature_tags": [],
                    "claim_creditor": null,
                    "claim_debtor": null,
                    "claim_guarantor": null,
                    "claim_security_provider": null,
                    "claim_arising_date": null,
                    "claim_maturity_date": null,
                    "claim_default_or_acceleration_date": null,
                    "claim_performance_date": null,
                    "claim_instrument_date": null,
                    "claim_instrument_identifier": null,
                    "claim_instrument_issuer": null,
                    "claim_principal_amount_at_act": null,
                    "claim_total_amount_at_act": null,
                    "claim_outstanding_amount_at_close": null,
                    "claim_actual_performance_amount": null,
                    "claim_guarantee_limit_amount": null,
                    "claim_secured_cap_amount": null,
                    "claim_interest_rate": null,
                    "claim_default_rate": null,
                    "claim_component_breakdown": [],
                    "claim_status_tags": []
                  }
                }
              
                추가 제약:
                - `legal_calculation_object`는 값이 있을 때만 포함한다.
                - `actio_pauliana_support`는 절대 포함하지 않는다.
                - 정의되지 않은 추가 필드 금지.
                </OUTPUT_SCHEMA>
              
                <VALIDATION_GATES>
                - same `evidence_index`의 multi-event 문서가 여러 Fact에 붙을 때, 각 Fact에 주입된 계산객체가 현재 BO semantic class와 직접 대응하는지 점검한다.
                - `sale_price`, `transaction_date`, `registration_date`가 현재 BO와 무관한 later transaction에서 온 것은 아닌지 점검한다.
                - `encumbrance_setting_class` Fact에 unrelated ownership transfer snapshot이 섞이지 않았는지 점검한다.
                - `loan_claim_class` Fact에 unrelated disposal snapshot이 섞이지 않았는지 점검한다.
                - safe slot이 없을 때는 `legal_calculation_object`를 생략했는지 점검한다.
                - 출력 파일명과 성공 메시지가 정확한지 점검한다.
                </VALIDATION_GATES>
              </STATIC_BLOCK_TASK_D1>
              
              <DYNAMIC_TAIL_TASK_D1>
                <CHECKLIST>
                [ ] 1) Preflight: `list_docs` 사용해서 `BO.json`, `evidence_indexed.json`만 확인하고, `read_docs` 사용해서 `BO.json`, `evidence_indexed.json`만 읽기
                [ ] 2) `write_file` 사용해서 `Fact_Ledger_base.json` 생성
                [ ] 3) `list_docs` 사용해서 `Fact_Ledger_base.json` 파일만 존재 확인(절대 읽기 금지)
                [ ] 4) `"Fact Ledger base 생성 완료"` 출력하고 작업을 끝낸다(terminate)
                </CHECKLIST>
              
                <RUNTIME_FILES>
                  <INPUT_FILES>
                  - `BO.json`
                  - `evidence_indexed.json`
                  </INPUT_FILES>
                  <OUTPUT_FILE>
                  - `Fact_Ledger_base.json`
                  </OUTPUT_FILE>
                </RUNTIME_FILES>
              
                <FINAL_REMINDERS>
                - `Fact_Ledger_base.json`은 절대 재읽지 않는다.
                - 성공 시 마지막 채팅 출력은 정확히 `"Fact Ledger base 생성 완료"` 한 줄만 사용한다.
                </FINAL_REMINDERS>
              </DYNAMIC_TAIL_TASK_D1>

        - task_name: Task_D2
          llm_provider: google
          llm_model: 'gemini-3.1-flash-lite-preview'
          llm_reasoning: medium
          cache_control:
            mode: auto
            ttl: 10m
          use_tools:
          - localdocs
          prompts:
          - role: user
            content: |-
              <ABSOLUTE_SYSTEM_RULES>
              - You MUST execute every single instruction provided below without any omission.
              - DO NOT arbitrarily reduce, summarize, or skip any steps, reasoning processes, or outputs.
              - DO NOT use placeholders like "..." or "rest of the code/text". Provide the exhaustive and complete output.
              - Adhere strictly to these rules before processing the prompt.
              </ABSOLUTE_SYSTEM_RULES>

              <COMMON_CACHE_PREFIX_STAGE_1>
                <STAGE_CONTEXT>
                당신은 대한민국 민사소송 원고대리 사건을 구조화하는 Stage 1 전용 정밀 LLM이다.
                이 프롬프트는 LLM의 안정적 추론, 구조 보존, 식별자 보존, 후속 단계 조인 안정성을 최우선으로 설계되었다.
                </STAGE_CONTEXT>
              
                <CACHE_HIT_POLICY>
                - 이 블록은 Stage 1의 Task_A, Task_B1, Task_B2, Task_B3, Task_C, Task_D1, Task_D2에서 byte-level로 최대한 동일하게 유지한다.
                - 이 블록 앞에는 어떤 문장도 두지 않는다.
                - 이 블록의 문구, 태그명, 순서, 공백, 줄바꿈, 구두점은 가급적 수정하지 않는다.
                - 각 Task prompt는 반드시 `<COMMON_CACHE_PREFIX_STAGE_1> -> <STATIC_BLOCK_TASK_X> -> <DYNAMIC_TAIL_TASK_X>` 순서로만 구성한다.
                </CACHE_HIT_POLICY>
              
                <GLOBAL_EXECUTION_RULES>
                - 현재 Task에서 허용한 Localdocs MCP 도구만 사용한다.
                - 오로지 추론(inference)과 MCP tool 호출만 사용한다.
                - 코드 생성, 코드 실행, 외부 웹 탐색, 허용되지 않은 파일 접근은 금지한다.
                - tool output만 사실로 취급한다.
                </GLOBAL_EXECUTION_RULES>
              
                <GROUNDING_AND_CONSERVATISM>
                - hallucination 금지.
                - 현재 Task에서 허용한 입력 파일에 없는 사건 고유 사실을 추가하지 않는다.
                - 다른 문서의 내용을 현재 문서에 이식하여 새 사실처럼 쓰지 않는다.
                - 불명확하면 현재 Task 계약이 허용하는 범위에서 `null`, `[]`, `"불명"`, `"[증거공백]"`을 사용한다.
                - 잘못된 값보다 빠진 값이 낫다.
                </GROUNDING_AND_CONSERVATISM>
              
                <AUTHORITY_AND_ID_DISCIPLINE>
                - authority 식별자는 그대로 유지한다.
                - `evidence_index`, `doc_uid`, `title`, `source_pointer.ordinal`, `candidate_id`, `bh#`, `F-###` 형식은 임의로 바꾸지 않는다.
                - 문서 순서, 배열 순서, 출력 파일명, 성공 메시지는 현재 Task가 명시한 값 그대로 유지한다.
                - 현재 Task가 기존 구조를 유지하라고 하면 필수 기존 필드를 제거하거나 이름을 바꾸지 않는다.
                - 현재 Task가 optional 확장 필드를 허용할 때만 additive 방식으로 추가한다.
                </AUTHORITY_AND_ID_DISCIPLINE>
              
                <XML_BOUNDARY_DISCIPLINE>
                - XML 태그는 하드 경계다.
                - 각 태그 안의 지시를 독립적으로 해석하고, 다른 태그의 규칙을 무단 확장하지 않는다.
                - 출력 계약 태그보다 느슨한 상식적 관행을 우선하지 않는다.
                </XML_BOUNDARY_DISCIPLINE>
              
                <FAIL_FAST_RULES>
                - 필수 입력이 누락되었거나, 빈 파일이거나, 파싱이 불가능하면 즉시 중단하고 출력 파일을 쓰지 않는다.
                - tool 오류가 발생하면 원인을 점검한 뒤 1회만 재시도한다.
                - 재시도 후에도 실패하면 해당 체크리스트 단계만 FAILED로 보고하고 종료한다.
                </FAIL_FAST_RULES>
              
                <BACKWARD_COMPATIBILITY_POLICY>
                - 현재 수정 대상이 아닌 Stage 1 다른 Task와의 호환을 해치지 않도록, 기존 필수 필드와 파일명은 유지한다.
                - schema 확장은 optional additive 방식으로만 수행한다.
                - 기존 필드가 위험하게 오염될 가능성이 있으면, 잘못된 요약값을 쓰지 말고 해당 필드를 생략하거나 `null`로 두는 쪽을 택한다.
                - multi-event 문서를 단일 snapshot으로 왜곡하여 downstream을 오염시키지 않는다.
                </BACKWARD_COMPATIBILITY_POLICY>
              </COMMON_CACHE_PREFIX_STAGE_1>
              
              <STATIC_BLOCK_TASK_D2>
                <TASK_META>
                  <TASK_NAME>Task_D2</TASK_NAME>
                  <ROLE>
                  You are an MCP-enabled LLM agent assisting plaintiff-side Korean civil/commercial litigation counsel.
                  </ROLE>
                  <MISSION>
                  `BO.json`, `evidence_actio_support.json`, `actio_case_signals.json`을 사용하여
                  각 BO에 연결된 sparse support 중 사건 전체에서 사해행위취소와 실질적으로 관련된 support만
                  BO 단위 normalized support object로 병합한 `fact_actio_support.json`을 생성한다.
                  이 단계의 핵심 목적은 case-level scope gate를 엄격히 적용하면서도,
                  linked evidence가 없는 preserved claim BO가 `actio_case_signals.preserved_claim_candidates`와 문서 내부 snapshot 정보로 식별되는 경우에는 보수적 fallback mapping을 허용하는 것이다.
                  </MISSION>
                </TASK_META>
              
                <ALLOWED_IO_AND_FORBIDDEN_ACTIONS>
                  <IN>
                  - `BO.json`
                  - `evidence_actio_support.json`
                  - `actio_case_signals.json`
                  </IN>
                  <OUT>
                  - `fact_actio_support.json`
                  </OUT>
                  <ABSOLUTE_FORBIDDEN>
                  - 다른 파일 확인/읽기
                  - 중간 파일 생성
                  - `fact_actio_support.json` 재읽기
                  - linked evidence 밖의 다른 support 문서를 끌어오기
                  - 계산, 합산, 차감, 최종 가액배상 한도 산정
                  - `fraudulent_act_date`를 비처분 BO에 올리기
                  - `plaintiff_claim_snapshots`를 비원고채권 BO에 올리기
                  </ABSOLUTE_FORBIDDEN>
                </ALLOWED_IO_AND_FORBIDDEN_ACTIONS>
              
                <EXECUTION_SEQUENCE>
                1. `list_docs`로 `BO.json`, `evidence_actio_support.json`, `actio_case_signals.json` 존재만 확인한다.
                2. `read_docs`로 위 세 파일만 읽는다.
                3. 사건 수준 gate가 닫혀 있으면 원칙적으로 `[]`를 저장한다.
                4. gate가 열려 있으면 `BO.json` 배열 순서대로 각 BO의 linked support를 식별한다.
                5. case scope anchors를 우선 적용하여 BO scope bucket을 판정한다.
                6. field별 relevance 필터를 적용해 허용되는 support만 남긴다.
                7. 필요한 경우 preserved claim BO에 한해 보수적 signal-fallback mapping을 수행한다.
                8. `write_file(overwrite=true)`로 `fact_actio_support.json`을 저장한다.
                9. `list_docs`로 파일 존재만 확인한다. 절대 읽지 않는다.
                10. 정확히 `"BO별 actio support 정규화 완료"`만 출력하고 종료한다.
                </EXECUTION_SEQUENCE>
              
                <FAILURE_POLICY>
                - 필수 입력 누락, 빈 파일, 파싱 불가: 즉시 중단하고 채팅으로만 보고한다. 파일은 쓰지 않는다.
                - tool 오류: 원인 확인 후 1회만 재시도한다. 재실패 시 `FAILED: <step>`만 보고하고 종료한다.
                </FAILURE_POLICY>
              
                <INPUT_CONTRACT>
                  <BO_RULES>
                  - `BO.json`은 배열이다.
                  - 각 BO는 `id`, `Performer`, `PerformerType`, `Action`, `ActionType`, `Subject`, `Reason`, `PriorAct`, `BehaviorTime`, `TimeText`, `TimePrecision`, `StatementType`, `Perspective`, `EvidenceTitles`, `Evidence[]`를 가진다.
                  - 선택적으로 `Object`, `Method`, `Location`, `Outcome`, `Legal_Keywords`, `JuristicAct`를 가질 수 있다.
                  </BO_RULES>
              
                  <EVIDENCE_SUPPORT_RULES>
                  - `evidence_actio_support.json`은 support가 있는 문서만 sparse하게 담은 배열이다.
                  - 각 원소는 `evidence_index`와 `actio_pauliana_support`를 가진다.
                  - `plaintiff_claim_snapshots` 내부에 아래 optional additive field가 있을 수 있다.
                    - `claim_arising_date_candidate`
                    - `creditor_candidate`
                    - `debtor_candidate`
                  - 이 optional field들은 preserved claim BO fallback 매핑 보조용이다.
                  </EVIDENCE_SUPPORT_RULES>
              
                  <CASE_SIGNAL_RULES>
                  - `actio_case_signals.json`은 case-level scope gate다.
                  - 주요 anchor:
                    - `related_bo_ids`
                    - `related_evidence_indexes`
                    - `target_property_candidates`
                    - `fraudulent_act_date_candidates`
                    - `preserved_claim_candidates`
                    - `beneficiary_candidates`
                    - `encumbrance_related_evidence_indexes`
                  </CASE_SIGNAL_RULES>
                </INPUT_CONTRACT>
              
                <GLOBAL_GATE_RULES>
                  <HARD_GATE>
                  - `is_actio_pauliana_suspected == false` 이고 `suspicion_level == "none"`이면 원칙적으로 `[]`를 저장한다.
                  - gate가 닫혀 있는데도 support를 확장하지 않는다.
                  </HARD_GATE>
              
                  <CASE_SCOPE_PRIORITY>
                  case-level scope anchor는 아래 우선순위를 따른다.
                  1. `related_bo_ids`
                  2. `related_evidence_indexes`
                  3. `target_property_candidates`
                  4. `fraudulent_act_date_candidates`
                  5. `preserved_claim_candidates`
                  6. `beneficiary_candidates`
                  7. `encumbrance_related_evidence_indexes`
                  </CASE_SCOPE_PRIORITY>
                </GLOBAL_GATE_RULES>
              
                <PRIMARY_MAPPING_RULES>
                  <SUPPORT_LOOKUP>
                  - `evidence_actio_support.json`을 `evidence_index` 기준 해시맵으로 만든다.
                  - 각 BO의 `Evidence[]`를 순회하여 `evidence_index`가 일치하는 support만 linked support로 채택한다.
                  - `evidence_index`가 `null`이거나 매칭 실패면 스킵한다.
                  - linked support가 0개면 원칙적으로 output 후보가 아니다.
                  </SUPPORT_LOOKUP>
              
                  <LINKED_SUPPORT_ORDER>
                  같은 BO에 연결된 linked support는 아래 우선순위로 정렬한다.
                  1. `evidence_index`가 `related_evidence_indexes`에 포함되면 최우선
                  2. encumbrance/lease/attachment 관련 병합에서는 `encumbrance_related_evidence_indexes`가 추가 우선
                  3. `BO.Evidence[].content_relevance`: `"직접"` > `"간접"` > `"불명"` > `"반대"`
                  4. support 내부 `proof_strength` 또는 `proof_status`: `"direct"` > `"indirect"` > `"meeting_only"` > `"unknown"`
                  5. `evidence_index` 오름차순
                  </LINKED_SUPPORT_ORDER>
                </PRIMARY_MAPPING_RULES>
              
                <SIGNAL_FALLBACK_MAPPING_RULES>
                - primary linked support가 없는 BO에 대해 무차별 fallback을 허용하지 않는다.
                - preserved claim BO에 한해서만 보수적 fallback을 허용한다.
                - fallback 허용 조건:
                  1. `BO.id`가 `actio_case_signals.preserved_claim_candidates[].bo_id`와 직접 일치하거나,
                  2. `preserved_claim_candidates`의 `creditor_candidate`/`debtor_candidate`가 `BO.Performer`/`BO.Subject`와 직접 부합한다.
                - fallback source는 `evidence_actio_support.json` 전체에서 `plaintiff_claim_snapshots`가 있는 record들뿐이다.
                - fallback snapshot 매칭 우선순위:
                  1. `claim_arising_date_candidate == BO.BehaviorTime`
                  2. `creditor_candidate`와 `debtor_candidate`가 BO 당사자와 직접 부합
                  3. `claim_type`과 `preserved_claim_candidates[].claim_type_candidate`가 직접 부합
                  4. 같은 `proof_doc` 안에 복수 snapshot이 있고 그중 1개만 날짜/당사자로 특정 가능하면 그 snapshot만 선택
                - 위 기준으로 1:1 대응이 명백하지 않으면 fallback mapping을 하지 않는다.
                - fallback mapping으로는 `plaintiff_claim_snapshots`와 이에 직접 대응하는 `support_role_tags=["원고채권"]`, 필요한 최소 `legal_meta_flags`만 허용한다.
                - fallback으로 property/encumbrance/beneficiary/lease/attachment field를 끌어오면 안 된다.
                - 동일 `proof_doc`가 서로 다른 날짜/당사자 snapshot을 직접 보여주면, 같은 문서를 두 개 이상의 BO에 재사용할 수 있다.
                </SIGNAL_FALLBACK_MAPPING_RULES>
              
                <SCOPE_BUCKET_RULES>
                각 BO는 아래 bucket 중 0개 이상에 속할 수 있다.
                - `property_bucket`
                - `preserved_claim_bucket`
                - `encumbrance_bucket`
                - `lease_bucket`
                - `attachment_bucket`
                - `beneficiary_bucket`
              
                판단 원칙:
                - `related_bo_ids`, `related_evidence_indexes`, `target_property_candidates`, `preserved_claim_candidates`, `beneficiary_candidates`, `encumbrance_related_evidence_indexes`를 우선한다.
                - BO의 `Action`, `Subject`, `Object`, `Legal_Keywords`, linked support role tag는 보조다.
                - 둘 사이가 애매하면 더 좁은 범위만 남긴다.
                - target property cluster와 연결이 불명하면 property/encumbrance/lease/attachment/beneficiary 관련 필드는 버린다.
                </SCOPE_BUCKET_RULES>
              
                <FIELD_RELEVANCE_RULES>
                  <SUPPORT_ROLE_TAGS>
                  - surviving 실질 support field를 실제로 뒷받침한 role tag만 남긴다.
                  - 단순 union 금지.
                  </SUPPORT_ROLE_TAGS>
              
                  <FRAUDULENT_ACT_DATE>
                  허용 조건:
                  - `property_bucket == true`
                  - role tag에 `사해행위목적물`이 존재
                  - 가능하면 `fraudulent_act_date_candidates`와 일치
                  충돌 시:
                  - 일치값 1개만 남기고, 복수/불일치이면 필드 전체 제거
                  </FRAUDULENT_ACT_DATE>
              
                  <PROPERTY_VALUE_CLOSE>
                  허용 조건:
                  - `property_bucket == true`
                  - 처분 목적물의 가치와 직접 연결
                  </PROPERTY_VALUE_CLOSE>
              
                  <ENCUMBRANCE_FIELDS>
                  허용 조건:
                  - `encumbrance_bucket == true`, 또는
                  - `property_bucket == true` 이고 같은 target property cluster 부담
                  금지:
                  - `preserved_claim_bucket`만 있는 BO에 올리지 않는다
                  </ENCUMBRANCE_FIELDS>
              
                  <LEASE_FIELD>
                  허용 조건:
                  - `lease_bucket == true`
                  - target property cluster와 직접 연결
                  </LEASE_FIELD>
              
                  <ATTACHMENT_FIELD>
                  허용 조건:
                  - `attachment_bucket == true`
                  - target property cluster와 직접 연결
                  </ATTACHMENT_FIELD>
              
                  <BENEFICIARY_GAIN_FIELD>
                  허용 조건:
                  - `beneficiary_bucket == true`, 또는
                  - `property_bucket == true` 이고 처분 상대방/수익자 관련성이 직접 드러남
                  </BENEFICIARY_GAIN_FIELD>
              
                  <PLAINTIFF_CLAIM_SNAPSHOTS>
                  허용 조건:
                  - `preserved_claim_bucket == true`
                  - 또는 signal-fallback mapping이 성공한 경우
                  금지:
                  - 처분 BO, 부담 BO, 임차권 BO, 가압류 BO에 자동 전파 금지
                  </PLAINTIFF_CLAIM_SNAPSHOTS>
              
                  <LEGAL_META_FLAGS>
                  - 동일 BO에서 실질 support field가 1개 이상 살아남았을 때만 보조적으로 유지한다.
                  - 실질 support field가 하나도 없으면 `legal_meta_flags` 전체를 버린다.
                  </LEGAL_META_FLAGS>
                </FIELD_RELEVANCE_RULES>
              
                <FIELD_MERGE_RULES>
                  <MERGE_PRINCIPLE>
                  - 스칼라는 first-non-null 원칙을 사용한다.
                  - 배열은 identity key 또는 exact-match 기준으로 최소 병합한다.
                  - 계산, 합산, 차감 금지.
                  </MERGE_PRINCIPLE>
              
                  <ENCUMBRANCE_IDENTITY>
                  - `encumbrances_at_fraudulent_act`, `encumbrances_at_close_of_arguments` identity key:
                    `kind + holder + rank`
                  - 같은 identity면 높은 우선순위 원소를 base로 쓰고 lower-priority 원소는 null 필드만 보충한다.
                  </ENCUMBRANCE_IDENTITY>
              
                  <NON_DEDUCTIBLE_ATTACHMENT_IDENTITY>
                  - `non_deductible_attachment_claims` identity key:
                    `holder + kind + claim_amount`
                  - 같은 identity면 exact-match 중복 제거, flag 충돌 시 `true` 우선.
                  </NON_DEDUCTIBLE_ATTACHMENT_IDENTITY>
              
                  <PLAINTIFF_SNAPSHOT_IDENTITY>
                  - `plaintiff_claim_snapshots` identity key:
                    `plaintiff_name + claim_type + claim_arising_date_candidate + creditor_candidate + debtor_candidate`
                  - 같은 identity면 높은 우선순위 원소를 base로 쓰고 null 필드만 보충한다.
                  - `proof_status`는 `"direct" > "indirect" > "meeting_only" > "unknown"` 우선.
                  </PLAINTIFF_SNAPSHOT_IDENTITY>
              
                  <META_SCORE_RULE>
                  - `confidence_score`는 `"high" > "medium" > "low" > "unknown"` 우선.
                  </META_SCORE_RULE>
                </FIELD_MERGE_RULES>
              
                <PRUNING_RULES>
                - 스칼라가 `null`이면 제거한다.
                - 배열이 비면 제거한다.
                - 객체 내부가 모두 제거되면 그 객체도 제거한다.
                - pruning 이후 `actio_pauliana_support`가 비면 해당 BO는 출력하지 않는다.
                - `proof_doc`는 surviving item의 입력값을 그대로 유지한다. 없으면 키를 제거한다.
                </PRUNING_RULES>
              
                <OUTPUT_SCHEMA>
                최종 파일은 배열(Array)이다.
              
                [
                  {
                    "source_bo_id": "bh1",
                    "actio_pauliana_support": {
                      "support_role_tags": ["사해행위목적물|선순위담보|존속담보|임차권|가압류|원고채권|수익자이익|법리메타"],
                      "fraudulent_act_date": "string",
                      "property_value_at_close_of_arguments_support": {
                        "candidate_amount": "string",
                        "candidate_date": "string",
                        "basis_type": "사실심변론종결직접|현재시점대체|감정기준일|거래시점동일|불명",
                        "reason_text": "string",
                        "confidence": "high|medium|low|unknown",
                        "proof_doc": "E-001"
                      },
                      "encumbrances_at_fraudulent_act": [],
                      "encumbrances_at_close_of_arguments": [],
                      "lease_deposit_deductibility_support": {},
                      "non_deductible_attachment_claims": [],
                      "beneficiary_gain_support": {},
                      "plaintiff_claim_snapshots": [],
                      "legal_meta_flags": {
                        "is_actio_pauliana_relevant_candidate": true,
                        "restoration_mode_candidate": "원물반환|말소등기|가액배상",
                        "is_value_compensation_exception_triggered_candidate": true,
                        "lease_deposit_deductible_candidate": true,
                        "attachment_claim_deductible_candidate": false,
                        "remaining_joint_collateral_value_estimate_candidate": "string",
                        "beneficiary_gain_estimate_candidate": "string",
                        "confidence_score": "high|medium|low|unknown"
                      }
                    }
                  }
                ]
              
                추가 제약:
                - 최상위 키는 `source_bo_id`, `actio_pauliana_support`만 허용한다.
                - `evidence_index`, `title`, `doc_type`, `key_*`, base `legal_calculation_object`, case-level signal 원문을 반복 저장하지 않는다.
                - 최종 배열이 비어 있을 수 있다.
                </OUTPUT_SCHEMA>
              
                <VALIDATION_GATES>
                - `fraudulent_act_date`가 원고채권 BO나 단순 변제 BO에 들어가지 않았는지 점검한다.
                - `plaintiff_claim_snapshots`가 preserved claim BO 또는 성공한 fallback BO에만 들어갔는지 점검한다.
                - linked evidence가 없는 preserved claim BO라도, fallback mapping 기준이 불충분하면 support를 억지로 붙이지 않았는지 점검한다.
                - 같은 `proof_doc`에서 복수 snapshot이 직접 구별되는 경우 각각의 BO에 적절히 재사용되었는지 점검한다.
                - `support_role_tags`가 surviving field와 실제로 대응하는지 점검한다.
                - pruning 이후 빈 support record가 남지 않았는지 점검한다.
                </VALIDATION_GATES>
              </STATIC_BLOCK_TASK_D2>
              
              <DYNAMIC_TAIL_TASK_D2>
                <CHECKLIST>
                [ ] 1) Preflight: `list_docs` 사용해서 `BO.json`, `evidence_actio_support.json`, `actio_case_signals.json`만 확인하고, `read_docs` 사용해서 `BO.json`, `evidence_actio_support.json`, `actio_case_signals.json`만 읽기
                [ ] 2) `write_file` 사용해서 `fact_actio_support.json` 생성
                [ ] 3) `list_docs` 사용해서 `fact_actio_support.json` 파일만 존재 확인(절대 읽기 금지)
                [ ] 4) `"BO별 actio support 정규화 완료"` 출력하고 작업을 끝낸다(terminate)
                </CHECKLIST>
              
                <RUNTIME_FILES>
                  <INPUT_FILES>
                  - `BO.json`
                  - `evidence_actio_support.json`
                  - `actio_case_signals.json`
                  </INPUT_FILES>
                  <OUTPUT_FILE>
                  - `fact_actio_support.json`
                  </OUTPUT_FILE>
                </RUNTIME_FILES>
              
                <FINAL_REMINDERS>
                - `fact_actio_support.json`은 절대 재읽지 않는다.
                - 성공 시 마지막 채팅 출력은 정확히 `"BO별 actio support 정규화 완료"` 한 줄만 사용한다.
                </FINAL_REMINDERS>
              </DYNAMIC_TAIL_TASK_D2>

        - task_name: Task_Display
          mcp: code-executor
          tool_name: run_code
          parameters:
            language: python
            requirements: "httpx"
            network: "agent-network"
            timeout: 180
            code: |
              #!/usr/bin/env python3
              from __future__ import annotations
              import html as _html
              import itertools
              import json
              import sys
              from datetime import date
              from typing import Any
              import httpx

              LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp"
              MCP_HEADERS = {"Content-Type": "application/json", "Accept": "application/json, text/event-stream"}
              CLIENT = httpx.Client(timeout=60)
              MSG_ID = itertools.count(10)
              def _mid(): return next(MSG_ID)
              def _init():
                  r = CLIENT.post(LOCALDOCS_URL, json={"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"task-display","version":"1.0","user_id":"{{__user_hash__}}","workspace_id":"{{__workspace_hash__}}"}}}, headers=MCP_HEADERS)
                  r.raise_for_status()
                  sid = r.headers.get("mcp-session-id")
                  if sid: MCP_HEADERS["mcp-session-id"] = sid
                  CLIENT.post(LOCALDOCS_URL, json={"jsonrpc":"2.0","method":"notifications/initialized"}, headers=MCP_HEADERS).raise_for_status()
              def _parse(text):
                  for line in text.strip().split("\n"):
                      if line.startswith("data: "):
                          try: return json.loads(line[6:])
                          except: pass
                  try: return json.loads(text)
                  except: return None
              def _call(name, args):
                  r = CLIENT.post(LOCALDOCS_URL, json={"jsonrpc":"2.0","id":_mid(),"method":"tools/call","params":{"name":name,"arguments":args}}, headers=MCP_HEADERS)
                  r.raise_for_status()
                  p = _parse(r.text)
                  if not p or "result" not in p: raise RuntimeError(f"MCP {name} failed")
                  return p
              def _unwrap(p, name):
                  text = (p["result"].get("content") or [{}])[0].get("text", "")
                  if not text: raise RuntimeError(f"Empty: {name}")
                  try: outer = json.loads(text)
                  except: return text
                  if isinstance(outer, dict) and "results" in outer:
                      r0 = (outer.get("results") or [{}])[0]
                      inner = r0.get("content") or r0.get("text") or ""
                      if not inner: raise RuntimeError(f"Empty content: {name}")
                      return inner if isinstance(inner, str) else json.dumps(inner, ensure_ascii=False)
                  return json.dumps(outer, ensure_ascii=False) if not isinstance(outer, str) else outer
              def read_json(name):
                  raw = _unwrap(_call("read_docs", {"doc_names": [name]}), name)
                  if not isinstance(raw, str): return raw
                  try:
                      return json.loads(raw)
                  except json.JSONDecodeError:
                      # Extra data 대응: 첫 번째 JSON 객체만 파싱
                      decoder = json.JSONDecoder()
                      obj, _ = decoder.raw_decode(raw.strip())
                      return obj
              def write_doc(path, content):
                  _call("write_file", {"path": path, "content": content, "overwrite": True})

              # ── helpers ──
              def _c(v):
                  if v is None: return ""
                  return str(v).strip() if not isinstance(v, str) else v.strip()
              def _h(v): return _html.escape(_c(v))
              def _dsort(v):
                  t = _c(v)
                  if not t: return (9999,12,31,"")
                  try: d = date.fromisoformat(t); return (d.year,d.month,d.day,t)
                  except: return (9999,12,31,t)
              def _chunk(items, n): return [items[i:i+n] for i in range(0,len(items),n)]
              def _wrap(t, mx=35):
                  r = _c(t)
                  if not r: return []
                  words, lines, cur = r.split(), [], ""
                  for w in words:
                      while len(w)>mx:
                          if cur: lines.append(cur); cur=""
                          lines.append(w[:mx]); w=w[mx:]
                      cand = w if not cur else f"{cur} {w}"
                      if len(cand)<=mx: cur=cand
                      else: lines.append(cur); cur=w
                  if cur: lines.append(cur)
                  return lines
              def _box(dt,body,eid=None):
                  L=[]
                  if _c(dt): L.append(_c(dt))
                  if _c(eid): L.extend(_wrap(f"[{_c(eid)}: {body}]"))
                  else: L.extend(_wrap(body))
                  return "<br/>".join(x for x in L if x)
              def _san(v): return _c(v).replace('"',"'").replace("\n"," ")
              def _seq_row(row,ri,pfx,dk,ddk,tk,idk=None,sid=False):
                  lines=["sequenceDiagram"]; pids=[]
                  for ii,(_,it) in enumerate(row,1):
                      pid=f"{pfx}_{ri}_{ii}"; pids.append(pid)
                      dt=_c(it.get(ddk)) if ddk else ""
                      if not dt: dt=_c(it.get(dk)) or "날짜 미상"
                      body=_c(it.get(tk)) or "(내용 없음)"
                      idt=_c(it.get(idk)) if sid and idk else None
                      alias=_san(_box(dt,body,idt))
                      lines.append(f"    participant {pid} as {json.dumps(alias,ensure_ascii=False)}")
                  for a,b in zip(pids,pids[1:]): lines.append(f"    {a}->>{b}: ")
                  return "\n".join(lines)
              def _seq_html(items,dk,ddk,tk,bpr,pfx,idk=None,sid=False):
                  ordered=sorted(enumerate(items),key=lambda p:(_dsort(p[1].get(dk)),p[0]))
                  if not ordered:
                      e='sequenceDiagram\n    participant empty as "표시할 항목이 없습니다."'
                      return f'<div class="timeline-stack"><div class="mermaid-block timeline-sequence-row"><pre class="mermaid">{e}</pre></div></div>'
                  rows=_chunk(ordered,bpr); parts=['<div class="timeline-stack">']
                  for ri,row in enumerate(rows,1):
                      d=_seq_row(row,ri,pfx,dk,ddk,tk,idk,sid)
                      parts.append(f'<div class="mermaid-block timeline-sequence-row"><pre class="mermaid">{d}</pre></div>')
                      if ri<len(rows): parts.append('<div class="timeline-arrow" aria-hidden="true">↓</div>')
                  parts.append("</div>"); return "\n".join(parts)
              def _constr(c):
                  if not isinstance(c,list) or not c: return "<p>(기재된 정보 없음)</p>"
                  items=[f"<li>{_h(i)}</li>" for i in c if _c(i)]
                  return "<ul>\n"+"\n".join(items)+"\n</ul>" if items else "<p>(기재된 정보 없음)</p>"
              def _evrows(el):
                  if not isinstance(el,list) or not el: return '<tr><td colspan="2">(문서 정보 없음)</td></tr>'
                  rows=[]
                  for i in el:
                      if not isinstance(i,dict): continue
                      rows.append(f"<tr><td>{_h(i.get('evidence_index')) or '&nbsp;'}</td><td>{_h(i.get('title_normalized')) or '&nbsp;'}</td></tr>")
                  return "\n".join(rows) if rows else '<tr><td colspan="2">(문서 정보 없음)</td></tr>'

              # ── main ──
              def main():
                  _init()
                  goal_data = read_json("client_goal.json")
                  evidence_list = read_json("evidence_indexed.json")
                  fact_list = read_json("Fact_Ledger_base.json")
                  pg=_h(goal_data.get("primary_goal")) or "(기재된 목표 없음)"
                  ch=_constr(goal_data.get("constraints"))
                  fh=_seq_html(fact_list,"date",None,"action",3,"fact","fact_id",True)
                  er=_evrows(evidence_list)
                  rendered = f"""<!DOCTYPE html>
              <html lang="ko"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>사건개요 시각화</title>
              <style>:root{{color-scheme:light;--page-bg:#f6f1e8;--card-bg:#fffdf9;--line:#d7c7b4;--text:#1f1a17;--muted:#665b52;--accent:#7f2f17}}*{{box-sizing:border-box}}body{{margin:0;font-family:"Iowan Old Style","Apple SD Gothic Neo","Noto Serif KR",serif;background:radial-gradient(circle at top,rgba(127,47,23,.12),transparent 28%),linear-gradient(180deg,#fcf7f0,var(--page-bg));color:var(--text)}}main{{max-width:1280px;margin:0 auto;padding:32px 20px 64px}}h1{{margin:0 0 24px;font-size:2.1rem;text-align:center}}section{{background:var(--card-bg);border:1px solid var(--line);border-radius:18px;padding:24px;margin-top:18px;box-shadow:0 12px 30px rgba(60,42,31,.06)}}h2{{margin:0 0 14px;color:var(--accent);font-size:1.25rem}}p,li,td,th{{line-height:1.65;font-size:.98rem}}p.section-label{{margin:0 0 8px;color:var(--muted)}}ul{{margin:10px 0 0 20px;padding:0}}.mermaid-block{{overflow-x:auto;border:1px solid #eadfce;border-radius:14px;background:#fffaf3;padding:12px}}.timeline-stack{{display:flex;flex-direction:column;align-items:center;gap:14px}}.timeline-sequence-row{{width:100%}}.timeline-arrow{{font-size:2rem;line-height:1;color:var(--accent);font-weight:700}}.mermaid{{margin:0;min-width:1400px;white-space:pre}}table{{width:100%;border-collapse:collapse}}th,td{{border:1px solid var(--line);padding:10px 12px;text-align:left;vertical-align:top}}th{{background:#f4e8d7}}@media(max-width:768px){{main{{padding:20px 14px 40px}}section{{padding:18px}}.mermaid{{min-width:1080px}}}}</style>
              <script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs";mermaid.initialize({{startOnLoad:true,securityLevel:"loose",sequence:{{mirrorActors:false}}}});</script>
              </head><body><main><h1>사건개요 시각화</h1>
              <section><h2>1. 기본 정보</h2><p class="section-label"><strong>원고의 목표</strong></p><p>{pg}</p><p class="section-label"><strong>소 제기를 위한 중요 정보</strong></p>{ch}</section>
              <section><h2>2. (법률)행위 타임라인</h2>{fh}</section>
              <section><h2>3. 서증 표</h2><table><thead><tr><th>문서 인덱스</th><th>문서 이름</th></tr></thead><tbody>{er}</tbody></table></section>
              </main></body></html>"""
                  write_doc("stage1.html", rendered)
                  write_doc("view_only/stage1.html", rendered)
                  print(f"[Task_Display] Done: stage1.html + view_only/stage1.html ({len(rendered)} chars)", file=sys.stderr)
                  print(json.dumps({"status": "ok", "output": "view_only/stage1.html", "size": len(rendered)}))

              if __name__ == "__main__":
                  main()

      task_procedure:
        IN:
          nexts: ["Task_A", "Task_B1"]
          wait_until: []
        Task_A:
          nexts: ["Task_Display"]
          wait_until: ["IN"]
        Task_B1:
          nexts: ["Task_B2"]
          wait_until: ["IN"]
        Task_B2:
          nexts: ["Task_C"]
          wait_until: ["Task_B1"]
        Task_C:
          nexts: ["Task_B3", "Task_D1"]
          wait_until: ["Task_B1", "Task_B2"]
        Task_B3:
          nexts: ["Task_D2"]
          wait_until: ["Task_B1", "Task_C"]
        Task_D1:
          nexts: ["Task_Display"]
          wait_until: ["Task_B1", "Task_C"]
        Task_D2:
          nexts: ["Task_Display"]
          wait_until: ["Task_B3", "Task_C"]
        Task_Display:
          nexts: ["OUT"]
          wait_until: ["Task_A", "Task_D1", "Task_D2"]
        OUT:
          nexts: []
          wait_until: ["Task_Display"]

      prevs: [ ]
      nexts: [stage_2_청구권개요서작성]

